{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "6x1ypzczQCwy"
   },
   "source": [
    "# Creating a Simple TFX Pipeline with the Penguin dataset\n",
    "\n",
    "## Learning objectives\n",
    "1. Prepare example data.\n",
    "2. Create a pipeline.\n",
    "3. Run the pipeline."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "_VuwrlnvQJ5k"
   },
   "source": [
    "## Introduction\n",
    "In this notebook, you will create and run a TFX pipeline\n",
    "for a simple classification model.\n",
    "The pipeline will consist of three essential TFX components: ExampleGen,\n",
    "Trainer and Pusher. The pipeline includes the most minimal ML workflow like\n",
    "importing data, training a model and exporting the trained model.\n",
    "\n",
    "Please see\n",
    "[Understanding TFX Pipelines](https://www.tensorflow.org/tfx/guide/understanding_tfx_pipelines)\n",
    "to learn more about various concepts in TFX.\n",
    "\n",
    "Each learning objective will correspond to a __#TODO__ in the [student lab notebook](../labs/penguin_simple.ipynb) -- try to complete that notebook first before reviewing this solution notebook."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "Fmgi8ZvQkScg"
   },
   "source": [
    "## Set Up\n",
    "You first need to install the TFX Python package and download\n",
    "the dataset which you will use for our model.\n",
    "\n",
    "### Upgrade Pip\n",
    "\n",
    "To avoid upgrading Pip in a system when running locally,\n",
    "check to make sure that you are running in Colab.\n",
    "Local systems can of course be upgraded separately."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "as4OTe2ukSqm",
    "outputId": "6660a20a-3e5c-42a5-9d12-55392589885a"
   },
   "outputs": [],
   "source": [
    "try:\n",
    "  import colab\n",
    "  !pip install --upgrade pip\n",
    "except:\n",
    "  pass"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "MZOYTt1RW4TK"
   },
   "source": [
    "### Install TFX\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "iyQtljP-qPHY",
    "outputId": "55a57bee-74d4-4112-8885-a2b5ec5e74fb"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Collecting tfx\n",
      "  Using cached tfx-1.7.1-py3-none-any.whl (2.5 MB)\n",
      "Collecting packaging<21,>=20\n",
      "  Using cached packaging-20.9-py2.py3-none-any.whl (40 kB)\n",
      "Collecting kubernetes<13,>=10.0.1\n",
      "  Using cached kubernetes-12.0.1-py2.py3-none-any.whl (1.7 MB)\n",
      "Requirement already satisfied: apache-beam[gcp]<3,>=2.36 in /opt/conda/lib/python3.7/site-packages (from tfx) (2.37.0)\n",
      "Collecting ml-metadata<1.8.0,>=1.7.0\n",
      "  Using cached ml_metadata-1.7.0-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (6.6 MB)\n",
      "Requirement already satisfied: tensorflow-serving-api!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,<3,>=1.15 in /opt/conda/lib/python3.7/site-packages (from tfx) (2.8.0)\n",
      "Requirement already satisfied: numpy<2,>=1.16 in /opt/conda/lib/python3.7/site-packages (from tfx) (1.19.5)\n",
      "Requirement already satisfied: google-cloud-aiplatform<2,>=1.6.2 in /opt/conda/lib/python3.7/site-packages (from tfx) (1.11.0)\n",
      "Requirement already satisfied: tensorflow-transform<1.8.0,>=1.7.0 in /opt/conda/lib/python3.7/site-packages (from tfx) (1.7.0)\n",
      "Collecting pyyaml<6,>=3.12\n",
      "  Using cached PyYAML-5.4.1-cp37-cp37m-manylinux1_x86_64.whl (636 kB)\n",
      "Requirement already satisfied: tensorflow-hub<0.13,>=0.9.0 in /opt/conda/lib/python3.7/site-packages (from tfx) (0.12.0)\n",
      "Requirement already satisfied: absl-py<2.0.0,>=0.9 in /opt/conda/lib/python3.7/site-packages (from tfx) (0.15.0)\n",
      "Collecting portpicker<2,>=1.3.1\n",
      "  Using cached portpicker-1.5.0-py3-none-any.whl (14 kB)\n",
      "Collecting pyarrow<6,>=1\n",
      "  Using cached pyarrow-5.0.0-cp37-cp37m-manylinux2014_x86_64.whl (23.6 MB)\n",
      "Collecting ml-pipelines-sdk==1.7.1\n",
      "  Downloading ml_pipelines_sdk-1.7.1-py3-none-any.whl (1.3 MB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.3/1.3 MB\u001b[0m \u001b[31m26.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0ma \u001b[36m0:00:01\u001b[0m\n",
      "\u001b[?25hRequirement already satisfied: tfx-bsl<1.8.0,>=1.7.0 in /opt/conda/lib/python3.7/site-packages (from tfx) (1.7.0)\n",
      "Collecting attrs<21,>=19.3.0\n",
      "  Downloading attrs-20.3.0-py2.py3-none-any.whl (49 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m49.3/49.3 KB\u001b[0m \u001b[31m7.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hCollecting google-api-python-client<2,>=1.8\n",
      "  Using cached google_api_python_client-1.12.11-py2.py3-none-any.whl (62 kB)\n",
      "Collecting tensorflow-data-validation<1.8.0,>=1.7.0\n",
      "  Downloading tensorflow_data_validation-1.7.0-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (1.4 MB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.4/1.4 MB\u001b[0m \u001b[31m62.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hRequirement already satisfied: keras-tuner<2,>=1.0.4 in /opt/conda/lib/python3.7/site-packages (from tfx) (1.1.0)\n",
      "Collecting docker<5,>=4.1\n",
      "  Using cached docker-4.4.4-py2.py3-none-any.whl (147 kB)\n",
      "Requirement already satisfied: google-cloud-bigquery<3,>=2.26.0 in /opt/conda/lib/python3.7/site-packages (from tfx) (2.34.2)\n",
      "Collecting tensorflow!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,<2.9,>=1.15.5\n",
      "  Using cached tensorflow-2.8.0-cp37-cp37m-manylinux2010_x86_64.whl (497.5 MB)\n",
      "Collecting tensorflow-model-analysis<0.39,>=0.38.0\n",
      "  Using cached tensorflow_model_analysis-0.38.0-py3-none-any.whl (1.8 MB)\n",
      "Collecting click<8,>=7\n",
      "  Using cached click-7.1.2-py2.py3-none-any.whl (82 kB)\n",
      "Requirement already satisfied: jinja2<4,>=2.7.3 in /opt/conda/lib/python3.7/site-packages (from tfx) (2.11.3)\n",
      "Requirement already satisfied: google-apitools<1,>=0.5 in /opt/conda/lib/python3.7/site-packages (from tfx) (0.5.31)\n",
      "Requirement already satisfied: grpcio<2,>=1.28.1 in /opt/conda/lib/python3.7/site-packages (from tfx) (1.44.0)\n",
      "Requirement already satisfied: protobuf<4,>=3.13 in /opt/conda/lib/python3.7/site-packages (from tfx) (3.19.4)\n",
      "Requirement already satisfied: six in /opt/conda/lib/python3.7/site-packages (from absl-py<2.0.0,>=0.9->tfx) (1.15.0)\n",
      "Requirement already satisfied: pymongo<4.0.0,>=3.8.0 in /opt/conda/lib/python3.7/site-packages (from apache-beam[gcp]<3,>=2.36->tfx) (3.12.3)\n",
      "Requirement already satisfied: cloudpickle<3,>=2.0.0 in /opt/conda/lib/python3.7/site-packages (from apache-beam[gcp]<3,>=2.36->tfx) (2.0.0)\n",
      "Requirement already satisfied: pydot<2,>=1.2.0 in /opt/conda/lib/python3.7/site-packages (from apache-beam[gcp]<3,>=2.36->tfx) (1.4.2)\n",
      "Requirement already satisfied: oauth2client<5,>=2.0.1 in /opt/conda/lib/python3.7/site-packages (from apache-beam[gcp]<3,>=2.36->tfx) (4.1.3)\n",
      "Requirement already satisfied: crcmod<2.0,>=1.7 in /opt/conda/lib/python3.7/site-packages (from apache-beam[gcp]<3,>=2.36->tfx) (1.7)\n",
      "Collecting dill<0.3.2,>=0.3.1.1\n",
      "  Downloading dill-0.3.1.1.tar.gz (151 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m152.0/152.0 KB\u001b[0m \u001b[31m21.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25h  Preparing metadata (setup.py) ... \u001b[?25ldone\n",
      "\u001b[?25hRequirement already satisfied: orjson<4.0 in /opt/conda/lib/python3.7/site-packages (from apache-beam[gcp]<3,>=2.36->tfx) (3.6.7)\n",
      "Requirement already satisfied: requests<3.0.0,>=2.24.0 in /opt/conda/lib/python3.7/site-packages (from apache-beam[gcp]<3,>=2.36->tfx) (2.27.1)\n",
      "Requirement already satisfied: fastavro<2,>=0.23.6 in /opt/conda/lib/python3.7/site-packages (from apache-beam[gcp]<3,>=2.36->tfx) (1.4.10)\n",
      "Requirement already satisfied: proto-plus<2,>=1.7.1 in /opt/conda/lib/python3.7/site-packages (from apache-beam[gcp]<3,>=2.36->tfx) (1.20.3)\n",
      "Requirement already satisfied: hdfs<3.0.0,>=2.1.0 in /opt/conda/lib/python3.7/site-packages (from apache-beam[gcp]<3,>=2.36->tfx) (2.6.0)\n",
      "Collecting httplib2<0.20.0,>=0.8\n",
      "  Downloading httplib2-0.19.1-py3-none-any.whl (95 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m95.4/95.4 KB\u001b[0m \u001b[31m12.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hRequirement already satisfied: python-dateutil<3,>=2.8.0 in /opt/conda/lib/python3.7/site-packages (from apache-beam[gcp]<3,>=2.36->tfx) (2.8.2)\n",
      "Requirement already satisfied: typing-extensions>=3.7.0 in /opt/conda/lib/python3.7/site-packages (from apache-beam[gcp]<3,>=2.36->tfx) (3.10.0.2)\n",
      "Requirement already satisfied: pytz>=2018.3 in /opt/conda/lib/python3.7/site-packages (from apache-beam[gcp]<3,>=2.36->tfx) (2021.3)\n",
      "Collecting google-cloud-spanner<2,>=1.13.0\n",
      "  Downloading google_cloud_spanner-1.19.2-py2.py3-none-any.whl (255 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m255.5/255.5 KB\u001b[0m \u001b[31m30.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hCollecting google-cloud-vision<2,>=0.38.0\n",
      "  Downloading google_cloud_vision-1.0.1-py2.py3-none-any.whl (435 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m435.1/435.1 KB\u001b[0m \u001b[31m43.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hRequirement already satisfied: google-cloud-dlp<4,>=3.0.0 in /opt/conda/lib/python3.7/site-packages (from apache-beam[gcp]<3,>=2.36->tfx) (3.6.2)\n",
      "Requirement already satisfied: google-cloud-bigquery-storage>=2.6.3 in /opt/conda/lib/python3.7/site-packages (from apache-beam[gcp]<3,>=2.36->tfx) (2.13.0)\n",
      "Requirement already satisfied: google-cloud-recommendations-ai<=0.2.0,>=0.1.0 in /opt/conda/lib/python3.7/site-packages (from apache-beam[gcp]<3,>=2.36->tfx) (0.2.0)\n",
      "Requirement already satisfied: google-cloud-pubsublite<2,>=1.2.0 in /opt/conda/lib/python3.7/site-packages (from apache-beam[gcp]<3,>=2.36->tfx) (1.4.1)\n",
      "Collecting google-cloud-datastore<2,>=1.8.0\n",
      "  Downloading google_cloud_datastore-1.15.4-py2.py3-none-any.whl (134 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m134.2/134.2 KB\u001b[0m \u001b[31m18.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hRequirement already satisfied: cachetools<5,>=3.1.0 in /opt/conda/lib/python3.7/site-packages (from apache-beam[gcp]<3,>=2.36->tfx) (4.2.4)\n",
      "Requirement already satisfied: grpcio-gcp<1,>=0.2.2 in /opt/conda/lib/python3.7/site-packages (from apache-beam[gcp]<3,>=2.36->tfx) (0.2.2)\n",
      "Collecting google-cloud-core<2,>=0.28.1\n",
      "  Downloading google_cloud_core-1.7.2-py2.py3-none-any.whl (28 kB)\n",
      "Collecting google-cloud-videointelligence<2,>=1.8.0\n",
      "  Downloading google_cloud_videointelligence-1.16.2-py2.py3-none-any.whl (183 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m183.9/183.9 KB\u001b[0m \u001b[31m23.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hRequirement already satisfied: google-auth<3,>=1.18.0 in /opt/conda/lib/python3.7/site-packages (from apache-beam[gcp]<3,>=2.36->tfx) (1.35.0)\n",
      "Requirement already satisfied: google-cloud-pubsub<3,>=2.1.0 in /opt/conda/lib/python3.7/site-packages (from apache-beam[gcp]<3,>=2.36->tfx) (2.11.0)\n",
      "Collecting google-cloud-bigtable<2,>=0.31.1\n",
      "  Downloading google_cloud_bigtable-1.7.1-py2.py3-none-any.whl (267 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m267.7/267.7 KB\u001b[0m \u001b[31m29.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hCollecting google-cloud-language<2,>=1.3.0\n",
      "  Downloading google_cloud_language-1.3.1-py2.py3-none-any.whl (83 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m83.6/83.6 KB\u001b[0m \u001b[31m13.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hRequirement already satisfied: websocket-client>=0.32.0 in /opt/conda/lib/python3.7/site-packages (from docker<5,>=4.1->tfx) (1.3.1)\n",
      "Requirement already satisfied: google-api-core<3dev,>=1.21.0 in /opt/conda/lib/python3.7/site-packages (from google-api-python-client<2,>=1.8->tfx) (2.5.0)\n",
      "Collecting uritemplate<4dev,>=3.0.0\n",
      "  Downloading uritemplate-3.0.1-py2.py3-none-any.whl (15 kB)\n",
      "Requirement already satisfied: google-auth-httplib2>=0.0.3 in /opt/conda/lib/python3.7/site-packages (from google-api-python-client<2,>=1.8->tfx) (0.1.0)\n",
      "Requirement already satisfied: fasteners>=0.14 in /opt/conda/lib/python3.7/site-packages (from google-apitools<1,>=0.5->tfx) (0.17.3)\n",
      "Requirement already satisfied: google-cloud-storage<3.0.0dev,>=1.32.0 in /opt/conda/lib/python3.7/site-packages (from google-cloud-aiplatform<2,>=1.6.2->tfx) (2.2.1)\n",
      "Requirement already satisfied: google-resumable-media<3.0dev,>=0.6.0 in /opt/conda/lib/python3.7/site-packages (from google-cloud-bigquery<3,>=2.26.0->tfx) (2.3.2)\n",
      "Requirement already satisfied: MarkupSafe>=0.23 in /opt/conda/lib/python3.7/site-packages (from jinja2<4,>=2.7.3->tfx) (2.0.1)\n",
      "Requirement already satisfied: kt-legacy in /opt/conda/lib/python3.7/site-packages (from keras-tuner<2,>=1.0.4->tfx) (1.0.4)\n",
      "Requirement already satisfied: tensorboard in /opt/conda/lib/python3.7/site-packages (from keras-tuner<2,>=1.0.4->tfx) (2.6.0)\n",
      "Requirement already satisfied: ipython in /opt/conda/lib/python3.7/site-packages (from keras-tuner<2,>=1.0.4->tfx) (7.32.0)\n",
      "Requirement already satisfied: scipy in /opt/conda/lib/python3.7/site-packages (from keras-tuner<2,>=1.0.4->tfx) (1.7.3)\n",
      "Requirement already satisfied: requests-oauthlib in /opt/conda/lib/python3.7/site-packages (from kubernetes<13,>=10.0.1->tfx) (1.3.1)\n",
      "Requirement already satisfied: setuptools>=21.0.0 in /opt/conda/lib/python3.7/site-packages (from kubernetes<13,>=10.0.1->tfx) (59.8.0)\n",
      "Requirement already satisfied: certifi>=14.05.14 in /opt/conda/lib/python3.7/site-packages (from kubernetes<13,>=10.0.1->tfx) (2021.10.8)\n",
      "Requirement already satisfied: urllib3>=1.24.2 in /opt/conda/lib/python3.7/site-packages (from kubernetes<13,>=10.0.1->tfx) (1.26.8)\n",
      "Requirement already satisfied: pyparsing>=2.0.2 in /opt/conda/lib/python3.7/site-packages (from packaging<21,>=20->tfx) (3.0.7)\n",
      "Requirement already satisfied: psutil in /opt/conda/lib/python3.7/site-packages (from portpicker<2,>=1.3.1->tfx) (5.9.0)\n",
      "Collecting libclang>=9.0.1\n",
      "  Downloading libclang-14.0.1-py2.py3-none-manylinux1_x86_64.whl (14.5 MB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m14.5/14.5 MB\u001b[0m \u001b[31m64.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m00:01\u001b[0m00:01\u001b[0m\n",
      "\u001b[?25hRequirement already satisfied: astunparse>=1.6.0 in /opt/conda/lib/python3.7/site-packages (from tensorflow!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,<2.9,>=1.15.5->tfx) (1.6.3)\n",
      "Requirement already satisfied: gast>=0.2.1 in /opt/conda/lib/python3.7/site-packages (from tensorflow!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,<2.9,>=1.15.5->tfx) (0.4.0)\n",
      "Requirement already satisfied: h5py>=2.9.0 in /opt/conda/lib/python3.7/site-packages (from tensorflow!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,<2.9,>=1.15.5->tfx) (3.1.0)\n",
      "Collecting tf-estimator-nightly==2.8.0.dev2021122109\n",
      "  Downloading tf_estimator_nightly-2.8.0.dev2021122109-py2.py3-none-any.whl (462 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m462.5/462.5 KB\u001b[0m \u001b[31m40.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hCollecting tensorflow-io-gcs-filesystem>=0.23.1\n",
      "  Downloading tensorflow_io_gcs_filesystem-0.25.0-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (2.1 MB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m2.1/2.1 MB\u001b[0m \u001b[31m73.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hRequirement already satisfied: wrapt>=1.11.0 in /opt/conda/lib/python3.7/site-packages (from tensorflow!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,<2.9,>=1.15.5->tfx) (1.12.1)\n",
      "Requirement already satisfied: opt-einsum>=2.3.2 in /opt/conda/lib/python3.7/site-packages (from tensorflow!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,<2.9,>=1.15.5->tfx) (3.3.0)\n",
      "Requirement already satisfied: keras-preprocessing>=1.1.1 in /opt/conda/lib/python3.7/site-packages (from tensorflow!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,<2.9,>=1.15.5->tfx) (1.1.2)\n",
      "Collecting tensorboard\n",
      "  Downloading tensorboard-2.8.0-py3-none-any.whl (5.8 MB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m5.8/5.8 MB\u001b[0m \u001b[31m84.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0mta \u001b[36m0:00:01\u001b[0m\n",
      "\u001b[?25hCollecting keras<2.9,>=2.8.0rc0\n",
      "  Downloading keras-2.8.0-py2.py3-none-any.whl (1.4 MB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.4/1.4 MB\u001b[0m \u001b[31m63.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hCollecting numpy<2,>=1.16\n",
      "  Downloading numpy-1.21.6-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (15.7 MB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m15.7/15.7 MB\u001b[0m \u001b[31m64.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m00:01\u001b[0m00:01\u001b[0m\n",
      "\u001b[?25hRequirement already satisfied: termcolor>=1.1.0 in /opt/conda/lib/python3.7/site-packages (from tensorflow!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,<2.9,>=1.15.5->tfx) (1.1.0)\n",
      "Requirement already satisfied: flatbuffers>=1.12 in /opt/conda/lib/python3.7/site-packages (from tensorflow!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,<2.9,>=1.15.5->tfx) (1.12)\n",
      "Requirement already satisfied: google-pasta>=0.1.1 in /opt/conda/lib/python3.7/site-packages (from tensorflow!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,<2.9,>=1.15.5->tfx) (0.2.0)\n",
      "Collecting pyfarmhash<0.4,>=0.2\n",
      "  Downloading pyfarmhash-0.3.2.tar.gz (99 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m99.9/99.9 KB\u001b[0m \u001b[31m16.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25h  Preparing metadata (setup.py) ... \u001b[?25ldone\n",
      "\u001b[?25hRequirement already satisfied: tensorflow-metadata<1.8,>=1.7.0 in /opt/conda/lib/python3.7/site-packages (from tensorflow-data-validation<1.8.0,>=1.7.0->tfx) (1.7.0)\n",
      "Requirement already satisfied: pandas<2,>=1.0 in /opt/conda/lib/python3.7/site-packages (from tensorflow-data-validation<1.8.0,>=1.7.0->tfx) (1.3.5)\n",
      "Collecting joblib<0.15,>=0.12\n",
      "  Downloading joblib-0.14.1-py2.py3-none-any.whl (294 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m294.9/294.9 KB\u001b[0m \u001b[31m33.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hRequirement already satisfied: ipywidgets<8,>=7 in /opt/conda/lib/python3.7/site-packages (from tensorflow-model-analysis<0.39,>=0.38.0->tfx) (7.6.5)\n",
      "Requirement already satisfied: wheel<1.0,>=0.23.0 in /opt/conda/lib/python3.7/site-packages (from astunparse>=1.6.0->tensorflow!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,<2.9,>=1.15.5->tfx) (0.37.1)\n",
      "Requirement already satisfied: googleapis-common-protos<2.0dev,>=1.52.0 in /opt/conda/lib/python3.7/site-packages (from google-api-core<3dev,>=1.21.0->google-api-python-client<2,>=1.8->tfx) (1.54.0)\n",
      "Requirement already satisfied: grpcio-status<2.0dev,>=1.33.2 in /opt/conda/lib/python3.7/site-packages (from google-api-core<3dev,>=1.21.0->google-api-python-client<2,>=1.8->tfx) (1.44.0)\n",
      "Requirement already satisfied: rsa<5,>=3.1.4 in /opt/conda/lib/python3.7/site-packages (from google-auth<3,>=1.18.0->apache-beam[gcp]<3,>=2.36->tfx) (4.8)\n",
      "Requirement already satisfied: pyasn1-modules>=0.2.1 in /opt/conda/lib/python3.7/site-packages (from google-auth<3,>=1.18.0->apache-beam[gcp]<3,>=2.36->tfx) (0.2.7)\n",
      "Requirement already satisfied: grpc-google-iam-v1<0.13dev,>=0.12.3 in /opt/conda/lib/python3.7/site-packages (from google-cloud-bigtable<2,>=0.31.1->apache-beam[gcp]<3,>=2.36->tfx) (0.12.3)\n",
      "Collecting google-cloud-core<2,>=0.28.1\n",
      "  Downloading google_cloud_core-1.7.1-py2.py3-none-any.whl (28 kB)\n",
      "  Downloading google_cloud_core-1.7.0-py2.py3-none-any.whl (28 kB)\n",
      "  Downloading google_cloud_core-1.6.0-py2.py3-none-any.whl (28 kB)\n",
      "  Downloading google_cloud_core-1.5.0-py2.py3-none-any.whl (27 kB)\n",
      "  Downloading google_cloud_core-1.4.4-py2.py3-none-any.whl (27 kB)\n",
      "  Downloading google_cloud_core-1.4.3-py2.py3-none-any.whl (27 kB)\n",
      "  Downloading google_cloud_core-1.4.2-py2.py3-none-any.whl (26 kB)\n",
      "  Downloading google_cloud_core-1.4.1-py2.py3-none-any.whl (26 kB)\n",
      "INFO: pip is looking at multiple versions of google-cloud-bigtable to determine which version is compatible with other requirements. This could take a while.\n",
      "Collecting google-cloud-bigtable<2,>=0.31.1\n",
      "  Downloading google_cloud_bigtable-1.7.0-py2.py3-none-any.whl (267 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m267.7/267.7 KB\u001b[0m \u001b[31m30.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hINFO: pip is looking at multiple versions of google-cloud-bigquery-storage to determine which version is compatible with other requirements. This could take a while.\n",
      "Collecting google-cloud-bigquery-storage>=2.6.3\n",
      "  Downloading google_cloud_bigquery_storage-2.13.1-py2.py3-none-any.whl (180 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m180.1/180.1 KB\u001b[0m \u001b[31m25.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hINFO: pip is looking at multiple versions of google-auth-httplib2 to determine which version is compatible with other requirements. This could take a while.\n",
      "Collecting google-auth-httplib2>=0.0.3\n",
      "  Downloading google_auth_httplib2-0.1.0-py2.py3-none-any.whl (9.3 kB)\n",
      "INFO: pip is looking at multiple versions of google-auth to determine which version is compatible with other requirements. This could take a while.\n",
      "Collecting google-auth<3,>=1.18.0\n",
      "  Downloading google_auth-2.6.6-py2.py3-none-any.whl (156 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m156.7/156.7 KB\u001b[0m \u001b[31m19.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25h  Downloading google_auth-1.35.0-py2.py3-none-any.whl (152 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m152.9/152.9 KB\u001b[0m \u001b[31m19.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hINFO: pip is looking at multiple versions of google-api-core[grpc] to determine which version is compatible with other requirements. This could take a while.\n",
      "Collecting google-api-core[grpc]!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.0,<3.0.0dev,>=1.31.5\n",
      "  Downloading google_api_core-2.7.3-py3-none-any.whl (114 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m114.6/114.6 KB\u001b[0m \u001b[31m15.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hINFO: pip is looking at multiple versions of google-api-core to determine which version is compatible with other requirements. This could take a while.\n",
      "  Downloading google_api_core-2.7.2-py3-none-any.whl (114 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m114.6/114.6 KB\u001b[0m \u001b[31m13.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25h  Downloading google_api_core-2.7.1-py3-none-any.whl (114 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m114.7/114.7 KB\u001b[0m \u001b[31m13.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25h  Downloading google_api_core-2.7.0-py3-none-any.whl (114 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m114.7/114.7 KB\u001b[0m \u001b[31m13.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25h  Downloading google_api_core-2.6.1-py3-none-any.whl (114 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m114.6/114.6 KB\u001b[0m \u001b[31m15.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25h  Downloading google_api_core-2.6.0-py2.py3-none-any.whl (114 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m114.6/114.6 KB\u001b[0m \u001b[31m16.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25h  Downloading google_api_core-2.5.0-py2.py3-none-any.whl (111 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m111.8/111.8 KB\u001b[0m \u001b[31m14.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hINFO: pip is looking at multiple versions of google-api-core[grpc] to determine which version is compatible with other requirements. This could take a while.\n",
      "  Downloading google_api_core-2.4.0-py2.py3-none-any.whl (111 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m111.7/111.7 KB\u001b[0m \u001b[31m14.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hINFO: pip is looking at multiple versions of google-api-core to determine which version is compatible with other requirements. This could take a while.\n",
      "  Downloading google_api_core-2.3.2-py2.py3-none-any.whl (109 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m109.8/109.8 KB\u001b[0m \u001b[31m16.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25h  Downloading google_api_core-1.31.5-py2.py3-none-any.whl (93 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m93.3/93.3 KB\u001b[0m \u001b[31m13.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hRequirement already satisfied: overrides<7.0.0,>=6.0.1 in /opt/conda/lib/python3.7/site-packages (from google-cloud-pubsublite<2,>=1.2.0->apache-beam[gcp]<3,>=2.36->tfx) (6.1.0)\n",
      "Requirement already satisfied: google-crc32c<2.0dev,>=1.0 in /opt/conda/lib/python3.7/site-packages (from google-resumable-media<3.0dev,>=0.6.0->google-cloud-bigquery<3,>=2.26.0->tfx) (1.1.2)\n",
      "Requirement already satisfied: cached-property in /opt/conda/lib/python3.7/site-packages (from h5py>=2.9.0->tensorflow!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,<2.9,>=1.15.5->tfx) (1.5.2)\n",
      "Requirement already satisfied: docopt in /opt/conda/lib/python3.7/site-packages (from hdfs<3.0.0,>=2.1.0->apache-beam[gcp]<3,>=2.36->tfx) (0.6.2)\n",
      "Collecting pyparsing>=2.0.2\n",
      "  Downloading pyparsing-2.4.7-py2.py3-none-any.whl (67 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m67.8/67.8 KB\u001b[0m \u001b[31m10.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hRequirement already satisfied: prompt-toolkit!=3.0.0,!=3.0.1,<3.1.0,>=2.0.0 in /opt/conda/lib/python3.7/site-packages (from ipython->keras-tuner<2,>=1.0.4->tfx) (3.0.27)\n",
      "Requirement already satisfied: jedi>=0.16 in /opt/conda/lib/python3.7/site-packages (from ipython->keras-tuner<2,>=1.0.4->tfx) (0.18.1)\n",
      "Requirement already satisfied: traitlets>=4.2 in /opt/conda/lib/python3.7/site-packages (from ipython->keras-tuner<2,>=1.0.4->tfx) (5.1.1)\n",
      "Requirement already satisfied: backcall in /opt/conda/lib/python3.7/site-packages (from ipython->keras-tuner<2,>=1.0.4->tfx) (0.2.0)\n",
      "Requirement already satisfied: pickleshare in /opt/conda/lib/python3.7/site-packages (from ipython->keras-tuner<2,>=1.0.4->tfx) (0.7.5)\n",
      "Requirement already satisfied: pexpect>4.3 in /opt/conda/lib/python3.7/site-packages (from ipython->keras-tuner<2,>=1.0.4->tfx) (4.8.0)\n",
      "Requirement already satisfied: pygments in /opt/conda/lib/python3.7/site-packages (from ipython->keras-tuner<2,>=1.0.4->tfx) (2.11.2)\n",
      "Requirement already satisfied: decorator in /opt/conda/lib/python3.7/site-packages (from ipython->keras-tuner<2,>=1.0.4->tfx) (5.1.1)\n",
      "Requirement already satisfied: matplotlib-inline in /opt/conda/lib/python3.7/site-packages (from ipython->keras-tuner<2,>=1.0.4->tfx) (0.1.3)\n",
      "Requirement already satisfied: widgetsnbextension~=3.5.0 in /opt/conda/lib/python3.7/site-packages (from ipywidgets<8,>=7->tensorflow-model-analysis<0.39,>=0.38.0->tfx) (3.5.2)\n",
      "Requirement already satisfied: ipython-genutils~=0.2.0 in /opt/conda/lib/python3.7/site-packages (from ipywidgets<8,>=7->tensorflow-model-analysis<0.39,>=0.38.0->tfx) (0.2.0)\n",
      "Requirement already satisfied: ipykernel>=4.5.1 in /opt/conda/lib/python3.7/site-packages (from ipywidgets<8,>=7->tensorflow-model-analysis<0.39,>=0.38.0->tfx) (6.9.2)\n",
      "Requirement already satisfied: nbformat>=4.2.0 in /opt/conda/lib/python3.7/site-packages (from ipywidgets<8,>=7->tensorflow-model-analysis<0.39,>=0.38.0->tfx) (5.2.0)\n",
      "Requirement already satisfied: jupyterlab-widgets>=1.0.0 in /opt/conda/lib/python3.7/site-packages (from ipywidgets<8,>=7->tensorflow-model-analysis<0.39,>=0.38.0->tfx) (1.0.2)\n",
      "Requirement already satisfied: pyasn1>=0.1.7 in /opt/conda/lib/python3.7/site-packages (from oauth2client<5,>=2.0.1->apache-beam[gcp]<3,>=2.36->tfx) (0.4.8)\n",
      "Requirement already satisfied: idna<4,>=2.5 in /opt/conda/lib/python3.7/site-packages (from requests<3.0.0,>=2.24.0->apache-beam[gcp]<3,>=2.36->tfx) (3.3)\n",
      "Requirement already satisfied: charset-normalizer~=2.0.0 in /opt/conda/lib/python3.7/site-packages (from requests<3.0.0,>=2.24.0->apache-beam[gcp]<3,>=2.36->tfx) (2.0.12)\n",
      "Requirement already satisfied: tensorboard-data-server<0.7.0,>=0.6.0 in /opt/conda/lib/python3.7/site-packages (from tensorboard->keras-tuner<2,>=1.0.4->tfx) (0.6.1)\n",
      "Requirement already satisfied: markdown>=2.6.8 in /opt/conda/lib/python3.7/site-packages (from tensorboard->keras-tuner<2,>=1.0.4->tfx) (3.3.6)\n",
      "Requirement already satisfied: tensorboard-plugin-wit>=1.6.0 in /opt/conda/lib/python3.7/site-packages (from tensorboard->keras-tuner<2,>=1.0.4->tfx) (1.8.1)\n",
      "Requirement already satisfied: google-auth-oauthlib<0.5,>=0.4.1 in /opt/conda/lib/python3.7/site-packages (from tensorboard->keras-tuner<2,>=1.0.4->tfx) (0.4.6)\n",
      "Requirement already satisfied: werkzeug>=0.11.15 in /opt/conda/lib/python3.7/site-packages (from tensorboard->keras-tuner<2,>=1.0.4->tfx) (2.0.3)\n",
      "Requirement already satisfied: oauthlib>=3.0.0 in /opt/conda/lib/python3.7/site-packages (from requests-oauthlib->kubernetes<13,>=10.0.1->tfx) (3.2.0)\n",
      "Requirement already satisfied: cffi>=1.0.0 in /opt/conda/lib/python3.7/site-packages (from google-crc32c<2.0dev,>=1.0->google-resumable-media<3.0dev,>=0.6.0->google-cloud-bigquery<3,>=2.26.0->tfx) (1.15.0)\n",
      "Requirement already satisfied: tornado<7.0,>=4.2 in /opt/conda/lib/python3.7/site-packages (from ipykernel>=4.5.1->ipywidgets<8,>=7->tensorflow-model-analysis<0.39,>=0.38.0->tfx) (6.1)\n",
      "Requirement already satisfied: nest-asyncio in /opt/conda/lib/python3.7/site-packages (from ipykernel>=4.5.1->ipywidgets<8,>=7->tensorflow-model-analysis<0.39,>=0.38.0->tfx) (1.5.4)\n",
      "Requirement already satisfied: debugpy<2.0,>=1.0.0 in /opt/conda/lib/python3.7/site-packages (from ipykernel>=4.5.1->ipywidgets<8,>=7->tensorflow-model-analysis<0.39,>=0.38.0->tfx) (1.5.1)\n",
      "Requirement already satisfied: jupyter-client<8.0 in /opt/conda/lib/python3.7/site-packages (from ipykernel>=4.5.1->ipywidgets<8,>=7->tensorflow-model-analysis<0.39,>=0.38.0->tfx) (7.1.2)\n",
      "Requirement already satisfied: parso<0.9.0,>=0.8.0 in /opt/conda/lib/python3.7/site-packages (from jedi>=0.16->ipython->keras-tuner<2,>=1.0.4->tfx) (0.8.3)\n",
      "Requirement already satisfied: importlib-metadata>=4.4 in /opt/conda/lib/python3.7/site-packages (from markdown>=2.6.8->tensorboard->keras-tuner<2,>=1.0.4->tfx) (4.11.3)\n",
      "Requirement already satisfied: jsonschema!=2.5.0,>=2.4 in /opt/conda/lib/python3.7/site-packages (from nbformat>=4.2.0->ipywidgets<8,>=7->tensorflow-model-analysis<0.39,>=0.38.0->tfx) (4.4.0)\n",
      "Requirement already satisfied: jupyter-core in /opt/conda/lib/python3.7/site-packages (from nbformat>=4.2.0->ipywidgets<8,>=7->tensorflow-model-analysis<0.39,>=0.38.0->tfx) (4.9.2)\n",
      "Requirement already satisfied: typing-utils>=0.0.3 in /opt/conda/lib/python3.7/site-packages (from overrides<7.0.0,>=6.0.1->google-cloud-pubsublite<2,>=1.2.0->apache-beam[gcp]<3,>=2.36->tfx) (0.1.0)\n",
      "Requirement already satisfied: ptyprocess>=0.5 in /opt/conda/lib/python3.7/site-packages (from pexpect>4.3->ipython->keras-tuner<2,>=1.0.4->tfx) (0.7.0)\n",
      "Requirement already satisfied: wcwidth in /opt/conda/lib/python3.7/site-packages (from prompt-toolkit!=3.0.0,!=3.0.1,<3.1.0,>=2.0.0->ipython->keras-tuner<2,>=1.0.4->tfx) (0.2.5)\n",
      "Requirement already satisfied: notebook>=4.4.1 in /opt/conda/lib/python3.7/site-packages (from widgetsnbextension~=3.5.0->ipywidgets<8,>=7->tensorflow-model-analysis<0.39,>=0.38.0->tfx) (6.4.10)\n",
      "Requirement already satisfied: pycparser in /opt/conda/lib/python3.7/site-packages (from cffi>=1.0.0->google-crc32c<2.0dev,>=1.0->google-resumable-media<3.0dev,>=0.6.0->google-cloud-bigquery<3,>=2.26.0->tfx) (2.21)\n",
      "Requirement already satisfied: zipp>=0.5 in /opt/conda/lib/python3.7/site-packages (from importlib-metadata>=4.4->markdown>=2.6.8->tensorboard->keras-tuner<2,>=1.0.4->tfx) (3.7.0)\n",
      "Requirement already satisfied: pyrsistent!=0.17.0,!=0.17.1,!=0.17.2,>=0.14.0 in /opt/conda/lib/python3.7/site-packages (from jsonschema!=2.5.0,>=2.4->nbformat>=4.2.0->ipywidgets<8,>=7->tensorflow-model-analysis<0.39,>=0.38.0->tfx) (0.18.1)\n",
      "Requirement already satisfied: importlib-resources>=1.4.0 in /opt/conda/lib/python3.7/site-packages (from jsonschema!=2.5.0,>=2.4->nbformat>=4.2.0->ipywidgets<8,>=7->tensorflow-model-analysis<0.39,>=0.38.0->tfx) (5.4.0)\n",
      "Requirement already satisfied: entrypoints in /opt/conda/lib/python3.7/site-packages (from jupyter-client<8.0->ipykernel>=4.5.1->ipywidgets<8,>=7->tensorflow-model-analysis<0.39,>=0.38.0->tfx) (0.4)\n",
      "Requirement already satisfied: pyzmq>=13 in /opt/conda/lib/python3.7/site-packages (from jupyter-client<8.0->ipykernel>=4.5.1->ipywidgets<8,>=7->tensorflow-model-analysis<0.39,>=0.38.0->tfx) (22.3.0)\n",
      "Requirement already satisfied: argon2-cffi in /opt/conda/lib/python3.7/site-packages (from notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7->tensorflow-model-analysis<0.39,>=0.38.0->tfx) (21.3.0)\n",
      "Requirement already satisfied: Send2Trash>=1.8.0 in /opt/conda/lib/python3.7/site-packages (from notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7->tensorflow-model-analysis<0.39,>=0.38.0->tfx) (1.8.0)\n",
      "Requirement already satisfied: nbconvert>=5 in /opt/conda/lib/python3.7/site-packages (from notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7->tensorflow-model-analysis<0.39,>=0.38.0->tfx) (6.4.4)\n",
      "Requirement already satisfied: prometheus-client in /opt/conda/lib/python3.7/site-packages (from notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7->tensorflow-model-analysis<0.39,>=0.38.0->tfx) (0.13.1)\n",
      "Requirement already satisfied: terminado>=0.8.3 in /opt/conda/lib/python3.7/site-packages (from notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7->tensorflow-model-analysis<0.39,>=0.38.0->tfx) (0.13.3)\n",
      "Requirement already satisfied: mistune<2,>=0.8.1 in /opt/conda/lib/python3.7/site-packages (from nbconvert>=5->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7->tensorflow-model-analysis<0.39,>=0.38.0->tfx) (0.8.4)\n",
      "Requirement already satisfied: pandocfilters>=1.4.1 in /opt/conda/lib/python3.7/site-packages (from nbconvert>=5->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7->tensorflow-model-analysis<0.39,>=0.38.0->tfx) (1.5.0)\n",
      "Requirement already satisfied: nbclient<0.6.0,>=0.5.0 in /opt/conda/lib/python3.7/site-packages (from nbconvert>=5->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7->tensorflow-model-analysis<0.39,>=0.38.0->tfx) (0.5.13)\n",
      "Requirement already satisfied: testpath in /opt/conda/lib/python3.7/site-packages (from nbconvert>=5->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7->tensorflow-model-analysis<0.39,>=0.38.0->tfx) (0.6.0)\n",
      "Requirement already satisfied: jupyterlab-pygments in /opt/conda/lib/python3.7/site-packages (from nbconvert>=5->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7->tensorflow-model-analysis<0.39,>=0.38.0->tfx) (0.1.2)\n",
      "Requirement already satisfied: defusedxml in /opt/conda/lib/python3.7/site-packages (from nbconvert>=5->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7->tensorflow-model-analysis<0.39,>=0.38.0->tfx) (0.7.1)\n",
      "Requirement already satisfied: beautifulsoup4 in /opt/conda/lib/python3.7/site-packages (from nbconvert>=5->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7->tensorflow-model-analysis<0.39,>=0.38.0->tfx) (4.10.0)\n",
      "Requirement already satisfied: bleach in /opt/conda/lib/python3.7/site-packages (from nbconvert>=5->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7->tensorflow-model-analysis<0.39,>=0.38.0->tfx) (4.1.0)\n",
      "Requirement already satisfied: argon2-cffi-bindings in /opt/conda/lib/python3.7/site-packages (from argon2-cffi->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7->tensorflow-model-analysis<0.39,>=0.38.0->tfx) (21.2.0)\n",
      "Requirement already satisfied: soupsieve>1.2 in /opt/conda/lib/python3.7/site-packages (from beautifulsoup4->nbconvert>=5->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7->tensorflow-model-analysis<0.39,>=0.38.0->tfx) (2.3.1)\n",
      "Requirement already satisfied: webencodings in /opt/conda/lib/python3.7/site-packages (from bleach->nbconvert>=5->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7->tensorflow-model-analysis<0.39,>=0.38.0->tfx) (0.5.1)\n",
      "Building wheels for collected packages: dill, pyfarmhash\n",
      "  Building wheel for dill (setup.py) ... \u001b[?25ldone\n",
      "\u001b[?25h  Created wheel for dill: filename=dill-0.3.1.1-py3-none-any.whl size=78544 sha256=9855447cc1d10b9184f394f5e37b2116b0d627af22617d1cac03581a86a82f8d\n",
      "  Stored in directory: /home/jupyter/.cache/pip/wheels/a4/61/fd/c57e374e580aa78a45ed78d5859b3a44436af17e22ca53284f\n",
      "  Building wheel for pyfarmhash (setup.py) ... \u001b[?25ldone\n",
      "\u001b[?25h  Created wheel for pyfarmhash: filename=pyfarmhash-0.3.2-cp37-cp37m-linux_x86_64.whl size=108627 sha256=3e92f2e156f2ef1669a6e5a772483573431b7826ea74e12c4beb795926d28a21\n",
      "  Stored in directory: /home/jupyter/.cache/pip/wheels/53/58/7a/3b040f3a2ee31908e3be916e32660db6db53621ce6eba838dc\n",
      "Successfully built dill pyfarmhash\n",
      "Installing collected packages: tf-estimator-nightly, pyfarmhash, libclang, keras, joblib, uritemplate, tensorflow-io-gcs-filesystem, pyyaml, pyparsing, portpicker, numpy, dill, click, attrs, pyarrow, packaging, ml-metadata, httplib2, docker, kubernetes, google-api-core, tensorboard, google-cloud-core, google-api-python-client, tensorflow, ml-pipelines-sdk, google-cloud-vision, google-cloud-videointelligence, google-cloud-spanner, google-cloud-language, google-cloud-datastore, google-cloud-bigtable, tensorflow-model-analysis, tensorflow-data-validation, tfx\n",
      "  Attempting uninstall: keras\n",
      "    Found existing installation: keras 2.6.0\n",
      "    Uninstalling keras-2.6.0:\n",
      "      Successfully uninstalled keras-2.6.0\n",
      "  Attempting uninstall: joblib\n",
      "    Found existing installation: joblib 1.0.1\n",
      "    Uninstalling joblib-1.0.1:\n",
      "      Successfully uninstalled joblib-1.0.1\n",
      "  Attempting uninstall: uritemplate\n",
      "    Found existing installation: uritemplate 4.1.1\n",
      "    Uninstalling uritemplate-4.1.1:\n",
      "      Successfully uninstalled uritemplate-4.1.1\n",
      "  Attempting uninstall: pyyaml\n",
      "    Found existing installation: PyYAML 6.0\n",
      "    Uninstalling PyYAML-6.0:\n",
      "      Successfully uninstalled PyYAML-6.0\n",
      "  Attempting uninstall: pyparsing\n",
      "    Found existing installation: pyparsing 3.0.7\n",
      "    Uninstalling pyparsing-3.0.7:\n",
      "      Successfully uninstalled pyparsing-3.0.7\n",
      "  Attempting uninstall: numpy\n",
      "    Found existing installation: numpy 1.19.5\n",
      "    Uninstalling numpy-1.19.5:\n",
      "      Successfully uninstalled numpy-1.19.5\n",
      "  Attempting uninstall: dill\n",
      "    Found existing installation: dill 0.3.4\n",
      "    Uninstalling dill-0.3.4:\n",
      "      Successfully uninstalled dill-0.3.4\n",
      "  Attempting uninstall: click\n",
      "    Found existing installation: click 8.0.4\n",
      "    Uninstalling click-8.0.4:\n",
      "      Successfully uninstalled click-8.0.4\n",
      "  Attempting uninstall: attrs\n",
      "    Found existing installation: attrs 21.4.0\n",
      "    Uninstalling attrs-21.4.0:\n",
      "      Successfully uninstalled attrs-21.4.0\n",
      "  Attempting uninstall: pyarrow\n",
      "    Found existing installation: pyarrow 7.0.0\n",
      "    Uninstalling pyarrow-7.0.0:\n",
      "      Successfully uninstalled pyarrow-7.0.0\n",
      "  Attempting uninstall: packaging\n",
      "    Found existing installation: packaging 21.3\n",
      "    Uninstalling packaging-21.3:\n",
      "      Successfully uninstalled packaging-21.3\n",
      "  Attempting uninstall: httplib2\n",
      "    Found existing installation: httplib2 0.20.4\n",
      "    Uninstalling httplib2-0.20.4:\n",
      "      Successfully uninstalled httplib2-0.20.4\n",
      "  Attempting uninstall: docker\n",
      "    Found existing installation: docker 5.0.3\n",
      "    Uninstalling docker-5.0.3:\n",
      "      Successfully uninstalled docker-5.0.3\n",
      "  Attempting uninstall: kubernetes\n",
      "    Found existing installation: kubernetes 23.3.0\n",
      "    Uninstalling kubernetes-23.3.0:\n",
      "      Successfully uninstalled kubernetes-23.3.0\n",
      "  Attempting uninstall: google-api-core\n",
      "    Found existing installation: google-api-core 2.5.0\n",
      "    Uninstalling google-api-core-2.5.0:\n",
      "      Successfully uninstalled google-api-core-2.5.0\n",
      "  Attempting uninstall: tensorboard\n",
      "    Found existing installation: tensorboard 2.6.0\n",
      "    Uninstalling tensorboard-2.6.0:\n",
      "      Successfully uninstalled tensorboard-2.6.0\n",
      "  Attempting uninstall: google-cloud-core\n",
      "    Found existing installation: google-cloud-core 2.2.3\n",
      "    Uninstalling google-cloud-core-2.2.3:\n",
      "      Successfully uninstalled google-cloud-core-2.2.3\n",
      "  Attempting uninstall: google-api-python-client\n",
      "    Found existing installation: google-api-python-client 2.41.0\n",
      "    Uninstalling google-api-python-client-2.41.0:\n",
      "      Successfully uninstalled google-api-python-client-2.41.0\n",
      "  Attempting uninstall: tensorflow\n",
      "    Found existing installation: tensorflow 2.6.3\n",
      "    Uninstalling tensorflow-2.6.3:\n",
      "      Successfully uninstalled tensorflow-2.6.3\n",
      "  Attempting uninstall: google-cloud-vision\n",
      "    Found existing installation: google-cloud-vision 2.7.1\n",
      "    Uninstalling google-cloud-vision-2.7.1:\n",
      "      Successfully uninstalled google-cloud-vision-2.7.1\n",
      "  Attempting uninstall: google-cloud-videointelligence\n",
      "    Found existing installation: google-cloud-videointelligence 2.6.1\n",
      "    Uninstalling google-cloud-videointelligence-2.6.1:\n",
      "      Successfully uninstalled google-cloud-videointelligence-2.6.1\n",
      "  Attempting uninstall: google-cloud-spanner\n",
      "    Found existing installation: google-cloud-spanner 3.13.0\n",
      "    Uninstalling google-cloud-spanner-3.13.0:\n",
      "      Successfully uninstalled google-cloud-spanner-3.13.0\n",
      "  Attempting uninstall: google-cloud-language\n",
      "    Found existing installation: google-cloud-language 2.4.1\n",
      "    Uninstalling google-cloud-language-2.4.1:\n",
      "      Successfully uninstalled google-cloud-language-2.4.1\n",
      "  Attempting uninstall: google-cloud-datastore\n",
      "    Found existing installation: google-cloud-datastore 2.5.1\n",
      "    Uninstalling google-cloud-datastore-2.5.1:\n",
      "      Successfully uninstalled google-cloud-datastore-2.5.1\n",
      "  Attempting uninstall: google-cloud-bigtable\n",
      "    Found existing installation: google-cloud-bigtable 2.7.0\n",
      "    Uninstalling google-cloud-bigtable-2.7.0:\n",
      "      Successfully uninstalled google-cloud-bigtable-2.7.0\n",
      "\u001b[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.\n",
      "tensorflow-io 0.21.0 requires tensorflow<2.7.0,>=2.6.0, but you have tensorflow 2.8.0 which is incompatible.\n",
      "tensorflow-io 0.21.0 requires tensorflow-io-gcs-filesystem==0.21.0, but you have tensorflow-io-gcs-filesystem 0.25.0 which is incompatible.\n",
      "statsmodels 0.13.2 requires packaging>=21.3, but you have packaging 20.9 which is incompatible.\n",
      "pandas-profiling 3.1.0 requires joblib~=1.0.1, but you have joblib 0.14.1 which is incompatible.\n",
      "cloud-tpu-client 0.10 requires google-api-python-client==1.8.0, but you have google-api-python-client 1.12.11 which is incompatible.\n",
      "black 22.1.0 requires click>=8.0.0, but you have click 7.1.2 which is incompatible.\u001b[0m\u001b[31m\n",
      "\u001b[0mSuccessfully installed attrs-20.3.0 click-7.1.2 dill-0.3.1.1 docker-4.4.4 google-api-core-1.31.5 google-api-python-client-1.12.11 google-cloud-bigtable-1.7.1 google-cloud-core-2.2.2 google-cloud-datastore-1.15.4 google-cloud-language-1.3.1 google-cloud-spanner-1.19.2 google-cloud-videointelligence-1.16.2 google-cloud-vision-1.0.1 httplib2-0.19.1 joblib-0.14.1 keras-2.8.0 kubernetes-12.0.1 libclang-14.0.1 ml-metadata-1.7.0 ml-pipelines-sdk-1.7.1 numpy-1.21.6 packaging-20.9 portpicker-1.5.0 pyarrow-5.0.0 pyfarmhash-0.3.2 pyparsing-2.4.7 pyyaml-5.4.1 tensorboard-2.8.0 tensorflow-2.8.0 tensorflow-data-validation-1.7.0 tensorflow-io-gcs-filesystem-0.25.0 tensorflow-model-analysis-0.38.0 tf-estimator-nightly-2.8.0.dev2021122109 tfx-1.7.1 uritemplate-3.0.1\n"
     ]
    }
   ],
   "source": [
    "!pip install -U tfx"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "EwT0nov5QO1M"
   },
   "source": [
    "**Note:** Restart the kernel before proceeding further (On the Notebook menu, click **Kernel** > **Restart Kernel**)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "BDnPgN8UJtzN"
   },
   "source": [
    "Check the TensorFlow and TFX versions."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "6jh7vKSRqPHb",
    "outputId": "07bb86f7-2628-4fb7-a92e-3aff49d20130"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "TensorFlow version: 2.8.0\n",
      "TFX version: 1.7.1\n"
     ]
    }
   ],
   "source": [
    "import tensorflow as tf\n",
    "print('TensorFlow version: {}'.format(tf.__version__))\n",
    "from tfx import v1 as tfx\n",
    "print('TFX version: {}'.format(tfx.__version__))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "aDtLdSkvqPHe"
   },
   "source": [
    "### Set up variables\n",
    "\n",
    "There are some variables used to define a pipeline. You can customize these\n",
    "variables as you want. By default all output from the pipeline will be\n",
    "generated under the current directory."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "id": "EcUseqJaE2XN"
   },
   "outputs": [],
   "source": [
    "import os\n",
    "\n",
    "PIPELINE_NAME = \"penguin-simple\"\n",
    "\n",
    "# Output directory to store artifacts generated from the pipeline.\n",
    "PIPELINE_ROOT = os.path.join('pipelines', PIPELINE_NAME)\n",
    "# Path to a SQLite DB file to use as an MLMD storage.\n",
    "METADATA_PATH = os.path.join('metadata', PIPELINE_NAME, 'metadata.db')\n",
    "# Output directory where created models from the pipeline will be exported.\n",
    "SERVING_MODEL_DIR = os.path.join('serving_model', PIPELINE_NAME)\n",
    "\n",
    "from absl import logging\n",
    "logging.set_verbosity(logging.INFO)  # Set default logging level."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "8F2SRwRLSYGa"
   },
   "source": [
    "### Prepare example data\n",
    "You will download the example dataset for use in our TFX pipeline. The dataset we\n",
    "are using is\n",
    "[Palmer Penguins dataset](https://allisonhorst.github.io/palmerpenguins/articles/intro.html)\n",
    "which is also used in other\n",
    "[TFX examples](https://github.com/tensorflow/tfx/tree/master/tfx/examples/penguin).\n",
    "\n",
    "There are four numeric features in this dataset:\n",
    "\n",
    "- culmen_length_mm\n",
    "- culmen_depth_mm\n",
    "- flipper_length_mm\n",
    "- body_mass_g\n",
    "\n",
    "All features were already normalized to have range [0,1]. you will build a\n",
    "classification model which predicts the `species` of penguins."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "11J7XiCq6AFP"
   },
   "source": [
    "Because TFX ExampleGen reads inputs from a directory, you need to create a\n",
    "directory and copy dataset to it."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "4fxMs6u86acP",
    "outputId": "ab0fae39-fee3-42d4-e49f-5004ce50bde5"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "('/tmp/tfx-datamkxmix41/data.csv', <http.client.HTTPMessage at 0x7f1e27462590>)"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import urllib.request\n",
    "import tempfile\n",
    "\n",
    "DATA_ROOT = tempfile.mkdtemp(prefix='tfx-data')  # Create a temporary directory.\n",
    "_data_url = 'https://raw.githubusercontent.com/tensorflow/tfx/master/tfx/examples/penguin/data/labelled/penguins_processed.csv'\n",
    "_data_filepath = os.path.join(DATA_ROOT, \"data.csv\")\n",
    "urllib.request.urlretrieve(_data_url, _data_filepath)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "ASpoNmxKSQjI"
   },
   "source": [
    "Take a quick look at the CSV file."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "-eSz28UDSnlG",
    "outputId": "06eb0734-9d39-4dd8-deba-25394984dde5"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "species,culmen_length_mm,culmen_depth_mm,flipper_length_mm,body_mass_g\n",
      "0,0.2545454545454545,0.6666666666666666,0.15254237288135594,0.2916666666666667\n",
      "0,0.26909090909090905,0.5119047619047618,0.23728813559322035,0.3055555555555556\n",
      "0,0.29818181818181805,0.5833333333333334,0.3898305084745763,0.1527777777777778\n",
      "0,0.16727272727272732,0.7380952380952381,0.3559322033898305,0.20833333333333334\n",
      "0,0.26181818181818167,0.892857142857143,0.3050847457627119,0.2638888888888889\n",
      "0,0.24727272727272717,0.5595238095238096,0.15254237288135594,0.2569444444444444\n",
      "0,0.25818181818181823,0.773809523809524,0.3898305084745763,0.5486111111111112\n",
      "0,0.32727272727272727,0.5357142857142859,0.1694915254237288,0.1388888888888889\n",
      "0,0.23636363636363636,0.9642857142857142,0.3220338983050847,0.3055555555555556\n"
     ]
    }
   ],
   "source": [
    "# TODO 1\n",
    "# Review the contents of the CSV file\n",
    "!head {_data_filepath}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "OTtQNq1DdVvG"
   },
   "source": [
    "You should be able to see five values. `species` is one of 0, 1 or 2, and all\n",
    "other features should have values between 0 and 1."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "nH6gizcpSwWV"
   },
   "source": [
    "## Create a pipeline\n",
    "\n",
    "TFX pipelines are defined using Python APIs. You will define a pipeline which\n",
    "consists of following three components.\n",
    "- CsvExampleGen: Reads in data files and convert them to TFX internal format\n",
    "for further processing. There are multiple\n",
    "[ExampleGen](https://www.tensorflow.org/tfx/guide/examplegen)s for various\n",
    "formats. In this tutorial, you will use CsvExampleGen which takes CSV file input.\n",
    "- Trainer: Trains an ML model.\n",
    "[Trainer component](https://www.tensorflow.org/tfx/guide/trainer) requires a\n",
    "model definition code from users. You can use TensorFlow APIs to specify how to\n",
    "train a model and save it in a _saved_model_ format.\n",
    "- Pusher: Copies the trained model outside of the TFX pipeline.\n",
    "[Pusher component](https://www.tensorflow.org/tfx/guide/pusher) can be thought\n",
    "of an deployment process of the trained ML model.\n",
    "\n",
    "Before actually define the pipeline, you need to write a model code for the\n",
    "Trainer component first."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "lOjDv93eS5xV"
   },
   "source": [
    "### Write model training code\n",
    "\n",
    "You will create a simple DNN model for classification using TensorFlow Keras\n",
    "API. This model training code will be saved to a separate file.\n",
    "\n",
    "In this tutorial you will use\n",
    "[Generic Trainer](https://www.tensorflow.org/tfx/guide/trainer#generic_trainer)\n",
    "of TFX which support Keras-based models. You need to write a Python file\n",
    "containing `run_fn` function, which is the entrypoint for the `Trainer`\n",
    "component."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "id": "aES7Hv5QTDK3"
   },
   "outputs": [],
   "source": [
    "_trainer_module_file = 'penguin_trainer.py'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "Gnc67uQNTDfW",
    "outputId": "bc9cebbb-645e-465f-cd67-d84ac5310c8c"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Writing penguin_trainer.py\n"
     ]
    }
   ],
   "source": [
    "%%writefile {_trainer_module_file}\n",
    "\n",
    "from typing import List\n",
    "from absl import logging\n",
    "import tensorflow as tf\n",
    "from tensorflow import keras\n",
    "from tensorflow_transform.tf_metadata import schema_utils\n",
    "\n",
    "from tfx import v1 as tfx\n",
    "from tfx_bsl.public import tfxio\n",
    "from tensorflow_metadata.proto.v0 import schema_pb2\n",
    "\n",
    "_FEATURE_KEYS = [\n",
    "    'culmen_length_mm', 'culmen_depth_mm', 'flipper_length_mm', 'body_mass_g'\n",
    "]\n",
    "_LABEL_KEY = 'species'\n",
    "\n",
    "_TRAIN_BATCH_SIZE = 20\n",
    "_EVAL_BATCH_SIZE = 10\n",
    "\n",
    "# Since we're not generating or creating a schema, you will instead create\n",
    "# a feature spec.  Since there are a fairly small number of features this is\n",
    "# manageable for this dataset.\n",
    "_FEATURE_SPEC = {\n",
    "    **{\n",
    "        feature: tf.io.FixedLenFeature(shape=[1], dtype=tf.float32)\n",
    "           for feature in _FEATURE_KEYS\n",
    "       },\n",
    "    _LABEL_KEY: tf.io.FixedLenFeature(shape=[1], dtype=tf.int64)\n",
    "}\n",
    "\n",
    "\n",
    "def _input_fn(file_pattern: List[str],\n",
    "              data_accessor: tfx.components.DataAccessor,\n",
    "              schema: schema_pb2.Schema,\n",
    "              batch_size: int = 200) -> tf.data.Dataset:\n",
    "  \"\"\"Generates features and label for training.\n",
    "\n",
    "  Args:\n",
    "    file_pattern: List of paths or patterns of input tfrecord files.\n",
    "    data_accessor: DataAccessor for converting input to RecordBatch.\n",
    "    schema: schema of the input data.\n",
    "    batch_size: representing the number of consecutive elements of returned\n",
    "      dataset to combine in a single batch\n",
    "\n",
    "  Returns:\n",
    "    A dataset that contains (features, indices) tuple where features is a\n",
    "      dictionary of Tensors, and indices is a single Tensor of label indices.\n",
    "  \"\"\"\n",
    "  return data_accessor.tf_dataset_factory(\n",
    "      file_pattern,\n",
    "      tfxio.TensorFlowDatasetOptions(\n",
    "          batch_size=batch_size, label_key=_LABEL_KEY),\n",
    "      schema=schema).repeat()\n",
    "\n",
    "\n",
    "def _build_keras_model() -> tf.keras.Model:\n",
    "  \"\"\"Creates a DNN Keras model for classifying penguin data.\n",
    "\n",
    "  Returns:\n",
    "    A Keras Model.\n",
    "  \"\"\"\n",
    "  # The model below is built with Functional API, please refer to\n",
    "  # https://www.tensorflow.org/guide/keras/overview for all API options.\n",
    "  inputs = [keras.layers.Input(shape=(1,), name=f) for f in _FEATURE_KEYS]\n",
    "  d = keras.layers.concatenate(inputs)\n",
    "  for _ in range(2):\n",
    "    d = keras.layers.Dense(8, activation='relu')(d)\n",
    "  outputs = keras.layers.Dense(3)(d)\n",
    "\n",
    "  model = keras.Model(inputs=inputs, outputs=outputs)\n",
    "  model.compile(\n",
    "      optimizer=keras.optimizers.Adam(1e-2),\n",
    "      loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),\n",
    "      metrics=[keras.metrics.SparseCategoricalAccuracy()])\n",
    "\n",
    "  model.summary(print_fn=logging.info)\n",
    "  return model\n",
    "\n",
    "\n",
    "# TFX Trainer will call this function.\n",
    "def run_fn(fn_args: tfx.components.FnArgs):\n",
    "  \"\"\"Train the model based on given args.\n",
    "\n",
    "  Args:\n",
    "    fn_args: Holds args used to train the model as name/value pairs.\n",
    "  \"\"\"\n",
    "\n",
    "  # This schema is usually either an output of SchemaGen or a manually-curated\n",
    "  # version provided by pipeline author. A schema can also derived from TFT\n",
    "  # graph if a Transform component is used. In the case when either is missing,\n",
    "  # `schema_from_feature_spec` could be used to generate schema from very simple\n",
    "  # feature_spec, but the schema returned would be very primitive.\n",
    "  schema = schema_utils.schema_from_feature_spec(_FEATURE_SPEC)\n",
    "\n",
    "  train_dataset = _input_fn(\n",
    "      fn_args.train_files,\n",
    "      fn_args.data_accessor,\n",
    "      schema,\n",
    "      batch_size=_TRAIN_BATCH_SIZE)\n",
    "  eval_dataset = _input_fn(\n",
    "      fn_args.eval_files,\n",
    "      fn_args.data_accessor,\n",
    "      schema,\n",
    "      batch_size=_EVAL_BATCH_SIZE)\n",
    "\n",
    "  model = _build_keras_model()\n",
    "  model.fit(\n",
    "      train_dataset,\n",
    "      steps_per_epoch=fn_args.train_steps,\n",
    "      validation_data=eval_dataset,\n",
    "      validation_steps=fn_args.eval_steps)\n",
    "\n",
    "  # The result of the training should be saved in `fn_args.serving_model_dir`\n",
    "  # directory.\n",
    "  model.save(fn_args.serving_model_dir, save_format='tf')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "blaw0rs-emEf"
   },
   "source": [
    "Now you have completed all preparation steps to build a TFX pipeline."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "w3OkNz3gTLwM"
   },
   "source": [
    "### Write a pipeline definition\n",
    "\n",
    "You define a function to create a TFX pipeline. A `Pipeline` object\n",
    "represents a TFX pipeline which can be run using one of pipeline\n",
    "orchestration systems that TFX supports.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "id": "M49yYVNBTPd4"
   },
   "outputs": [],
   "source": [
    "# TODO 2\n",
    "def _create_pipeline(pipeline_name: str, pipeline_root: str, data_root: str,\n",
    "                     module_file: str, serving_model_dir: str,\n",
    "                     metadata_path: str) -> tfx.dsl.Pipeline:\n",
    "  \"\"\"Creates a three component penguin pipeline with TFX.\"\"\"\n",
    "  # Brings data into the pipeline.\n",
    "  example_gen = tfx.components.CsvExampleGen(input_base=data_root)\n",
    "\n",
    "  # Uses user-provided Python function that trains a model.\n",
    "  trainer = tfx.components.Trainer(\n",
    "      module_file=module_file,\n",
    "      examples=example_gen.outputs['examples'],\n",
    "      train_args=tfx.proto.TrainArgs(num_steps=100),\n",
    "      eval_args=tfx.proto.EvalArgs(num_steps=5))\n",
    "\n",
    "  # Pushes the model to a filesystem destination.\n",
    "  pusher = tfx.components.Pusher(\n",
    "      model=trainer.outputs['model'],\n",
    "      push_destination=tfx.proto.PushDestination(\n",
    "          filesystem=tfx.proto.PushDestination.Filesystem(\n",
    "              base_directory=serving_model_dir)))\n",
    "\n",
    "  # Following three components will be included in the pipeline.\n",
    "  components = [\n",
    "      example_gen,\n",
    "      trainer,\n",
    "      pusher,\n",
    "  ]\n",
    "\n",
    "  return tfx.dsl.Pipeline(\n",
    "      pipeline_name=pipeline_name,\n",
    "      pipeline_root=pipeline_root,\n",
    "      metadata_connection_config=tfx.orchestration.metadata\n",
    "      .sqlite_metadata_connection_config(metadata_path),\n",
    "      components=components)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "mJbq07THU2GV"
   },
   "source": [
    "## Run the pipeline\n",
    "\n",
    "TFX supports multiple orchestrators to run pipelines.\n",
    "In this tutorial you will use `LocalDagRunner` which is included in the TFX\n",
    "Python package and runs pipelines on local environment.\n",
    "You often call TFX pipelines \"DAGs\" which stands for directed acyclic graph.\n",
    "\n",
    "`LocalDagRunner` provides fast iterations for developemnt and debugging.\n",
    "TFX also supports other orchestrators including Kubeflow Pipelines and Apache\n",
    "Airflow which are suitable for production use cases.\n",
    "\n",
    "See\n",
    "[TFX on Cloud AI Platform Pipelines](https://www.tensorflow.org/tfx/tutorials/tfx/cloud-ai-platform-pipelines)\n",
    "or\n",
    "[TFX Airflow Tutorial](https://www.tensorflow.org/tfx/tutorials/tfx/airflow_workshop)\n",
    "to learn more about other orchestration systems."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "7mp0AkmrPdUb"
   },
   "source": [
    "Now you create a `LocalDagRunner` and pass a `Pipeline` object created from the\n",
    "function you already defined.\n",
    "\n",
    "The pipeline runs directly and you can see logs for the progress of the pipeline including ML model training."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 1000
    },
    "id": "fAtfOZTYWJu-",
    "outputId": "126e4374-09c7-422b-b52d-48b906ba1aa8"
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:absl:Generating ephemeral wheel package for '/home/jupyter/penguin_trainer.py' (including modules: ['penguin_trainer']).\n",
      "INFO:absl:User module package has hash fingerprint version a7e2e8dccbb913b74904edeec5549d868a2ea392bcd84fbc1965aba698dce3fc.\n",
      "INFO:absl:Executing: ['/opt/conda/bin/python', '/tmp/tmpyjemnwug/_tfx_generated_setup.py', 'bdist_wheel', '--bdist-dir', '/tmp/tmpxepaql1l', '--dist-dir', '/tmp/tmp_h09x9lz']\n",
      "/opt/conda/lib/python3.7/site-packages/setuptools/command/install.py:37: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.\n",
      "  setuptools.SetuptoolsDeprecationWarning,\n",
      "INFO:absl:Successfully built user code wheel distribution at 'pipelines/penguin-simple/_wheels/tfx_user_code_Trainer-0.0+a7e2e8dccbb913b74904edeec5549d868a2ea392bcd84fbc1965aba698dce3fc-py3-none-any.whl'; target user module is 'penguin_trainer'.\n",
      "INFO:absl:Full user module path is 'penguin_trainer@pipelines/penguin-simple/_wheels/tfx_user_code_Trainer-0.0+a7e2e8dccbb913b74904edeec5549d868a2ea392bcd84fbc1965aba698dce3fc-py3-none-any.whl'\n",
      "INFO:absl:Using deployment config:\n",
      " executor_specs {\n",
      "  key: \"CsvExampleGen\"\n",
      "  value {\n",
      "    beam_executable_spec {\n",
      "      python_executor_spec {\n",
      "        class_path: \"tfx.components.example_gen.csv_example_gen.executor.Executor\"\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "}\n",
      "executor_specs {\n",
      "  key: \"Pusher\"\n",
      "  value {\n",
      "    python_class_executable_spec {\n",
      "      class_path: \"tfx.components.pusher.executor.Executor\"\n",
      "    }\n",
      "  }\n",
      "}\n",
      "executor_specs {\n",
      "  key: \"Trainer\"\n",
      "  value {\n",
      "    python_class_executable_spec {\n",
      "      class_path: \"tfx.components.trainer.executor.GenericExecutor\"\n",
      "    }\n",
      "  }\n",
      "}\n",
      "custom_driver_specs {\n",
      "  key: \"CsvExampleGen\"\n",
      "  value {\n",
      "    python_class_executable_spec {\n",
      "      class_path: \"tfx.components.example_gen.driver.FileBasedDriver\"\n",
      "    }\n",
      "  }\n",
      "}\n",
      "metadata_connection_config {\n",
      "  database_connection_config {\n",
      "    sqlite {\n",
      "      filename_uri: \"metadata/penguin-simple/metadata.db\"\n",
      "      connection_mode: READWRITE_OPENCREATE\n",
      "    }\n",
      "  }\n",
      "}\n",
      "\n",
      "INFO:absl:Using connection config:\n",
      " sqlite {\n",
      "  filename_uri: \"metadata/penguin-simple/metadata.db\"\n",
      "  connection_mode: READWRITE_OPENCREATE\n",
      "}\n",
      "\n",
      "INFO:absl:Component CsvExampleGen is running.\n",
      "INFO:absl:Running launcher for node_info {\n",
      "  type {\n",
      "    name: \"tfx.components.example_gen.csv_example_gen.component.CsvExampleGen\"\n",
      "  }\n",
      "  id: \"CsvExampleGen\"\n",
      "}\n",
      "contexts {\n",
      "  contexts {\n",
      "    type {\n",
      "      name: \"pipeline\"\n",
      "    }\n",
      "    name {\n",
      "      field_value {\n",
      "        string_value: \"penguin-simple\"\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "  contexts {\n",
      "    type {\n",
      "      name: \"pipeline_run\"\n",
      "    }\n",
      "    name {\n",
      "      field_value {\n",
      "        string_value: \"2022-05-11T10:22:09.910052\"\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "  contexts {\n",
      "    type {\n",
      "      name: \"node\"\n",
      "    }\n",
      "    name {\n",
      "      field_value {\n",
      "        string_value: \"penguin-simple.CsvExampleGen\"\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "}\n",
      "outputs {\n",
      "  outputs {\n",
      "    key: \"examples\"\n",
      "    value {\n",
      "      artifact_spec {\n",
      "        type {\n",
      "          name: \"Examples\"\n",
      "          properties {\n",
      "            key: \"span\"\n",
      "            value: INT\n",
      "          }\n",
      "          properties {\n",
      "            key: \"split_names\"\n",
      "            value: STRING\n",
      "          }\n",
      "          properties {\n",
      "            key: \"version\"\n",
      "            value: INT\n",
      "          }\n",
      "          base_type: DATASET\n",
      "        }\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "}\n",
      "parameters {\n",
      "  parameters {\n",
      "    key: \"input_base\"\n",
      "    value {\n",
      "      field_value {\n",
      "        string_value: \"/tmp/tfx-datamkxmix41\"\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "  parameters {\n",
      "    key: \"input_config\"\n",
      "    value {\n",
      "      field_value {\n",
      "        string_value: \"{\\n  \\\"splits\\\": [\\n    {\\n      \\\"name\\\": \\\"single_split\\\",\\n      \\\"pattern\\\": \\\"*\\\"\\n    }\\n  ]\\n}\"\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "  parameters {\n",
      "    key: \"output_config\"\n",
      "    value {\n",
      "      field_value {\n",
      "        string_value: \"{\\n  \\\"split_config\\\": {\\n    \\\"splits\\\": [\\n      {\\n        \\\"hash_buckets\\\": 2,\\n        \\\"name\\\": \\\"train\\\"\\n      },\\n      {\\n        \\\"hash_buckets\\\": 1,\\n        \\\"name\\\": \\\"eval\\\"\\n      }\\n    ]\\n  }\\n}\"\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "  parameters {\n",
      "    key: \"output_data_format\"\n",
      "    value {\n",
      "      field_value {\n",
      "        int_value: 6\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "  parameters {\n",
      "    key: \"output_file_format\"\n",
      "    value {\n",
      "      field_value {\n",
      "        int_value: 5\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "}\n",
      "downstream_nodes: \"Trainer\"\n",
      "execution_options {\n",
      "  caching_options {\n",
      "  }\n",
      "}\n",
      "\n",
      "INFO:absl:MetadataStore with DB connection initialized\n",
      "INFO:absl:select span and version = (0, None)\n",
      "INFO:absl:latest span and version = (0, None)\n",
      "INFO:absl:MetadataStore with DB connection initialized\n",
      "INFO:absl:Going to run a new execution 1\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "running bdist_wheel\n",
      "running build\n",
      "running build_py\n",
      "creating build\n",
      "creating build/lib\n",
      "copying penguin_trainer.py -> build/lib\n",
      "installing to /tmp/tmpxepaql1l\n",
      "running install\n",
      "running install_lib\n",
      "copying build/lib/penguin_trainer.py -> /tmp/tmpxepaql1l\n",
      "running install_egg_info\n",
      "running egg_info\n",
      "creating tfx_user_code_Trainer.egg-info\n",
      "writing tfx_user_code_Trainer.egg-info/PKG-INFO\n",
      "writing dependency_links to tfx_user_code_Trainer.egg-info/dependency_links.txt\n",
      "writing top-level names to tfx_user_code_Trainer.egg-info/top_level.txt\n",
      "writing manifest file 'tfx_user_code_Trainer.egg-info/SOURCES.txt'\n",
      "reading manifest file 'tfx_user_code_Trainer.egg-info/SOURCES.txt'\n",
      "writing manifest file 'tfx_user_code_Trainer.egg-info/SOURCES.txt'\n",
      "Copying tfx_user_code_Trainer.egg-info to /tmp/tmpxepaql1l/tfx_user_code_Trainer-0.0+a7e2e8dccbb913b74904edeec5549d868a2ea392bcd84fbc1965aba698dce3fc-py3.7.egg-info\n",
      "running install_scripts\n",
      "creating /tmp/tmpxepaql1l/tfx_user_code_Trainer-0.0+a7e2e8dccbb913b74904edeec5549d868a2ea392bcd84fbc1965aba698dce3fc.dist-info/WHEEL\n",
      "creating '/tmp/tmp_h09x9lz/tfx_user_code_Trainer-0.0+a7e2e8dccbb913b74904edeec5549d868a2ea392bcd84fbc1965aba698dce3fc-py3-none-any.whl' and adding '/tmp/tmpxepaql1l' to it\n",
      "adding 'penguin_trainer.py'\n",
      "adding 'tfx_user_code_Trainer-0.0+a7e2e8dccbb913b74904edeec5549d868a2ea392bcd84fbc1965aba698dce3fc.dist-info/METADATA'\n",
      "adding 'tfx_user_code_Trainer-0.0+a7e2e8dccbb913b74904edeec5549d868a2ea392bcd84fbc1965aba698dce3fc.dist-info/WHEEL'\n",
      "adding 'tfx_user_code_Trainer-0.0+a7e2e8dccbb913b74904edeec5549d868a2ea392bcd84fbc1965aba698dce3fc.dist-info/top_level.txt'\n",
      "adding 'tfx_user_code_Trainer-0.0+a7e2e8dccbb913b74904edeec5549d868a2ea392bcd84fbc1965aba698dce3fc.dist-info/RECORD'\n",
      "removing /tmp/tmpxepaql1l\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:absl:Going to run a new execution: ExecutionInfo(execution_id=1, input_dict={}, output_dict=defaultdict(<class 'list'>, {'examples': [Artifact(artifact: uri: \"pipelines/penguin-simple/CsvExampleGen/examples/1\"\n",
      "custom_properties {\n",
      "  key: \"input_fingerprint\"\n",
      "  value {\n",
      "    string_value: \"split:single_split,num_files:1,total_bytes:25648,xor_checksum:1652264510,sum_checksum:1652264510\"\n",
      "  }\n",
      "}\n",
      "custom_properties {\n",
      "  key: \"name\"\n",
      "  value {\n",
      "    string_value: \"penguin-simple:2022-05-11T10:22:09.910052:CsvExampleGen:examples:0\"\n",
      "  }\n",
      "}\n",
      "custom_properties {\n",
      "  key: \"span\"\n",
      "  value {\n",
      "    int_value: 0\n",
      "  }\n",
      "}\n",
      ", artifact_type: name: \"Examples\"\n",
      "properties {\n",
      "  key: \"span\"\n",
      "  value: INT\n",
      "}\n",
      "properties {\n",
      "  key: \"split_names\"\n",
      "  value: STRING\n",
      "}\n",
      "properties {\n",
      "  key: \"version\"\n",
      "  value: INT\n",
      "}\n",
      "base_type: DATASET\n",
      ")]}), exec_properties={'output_config': '{\\n  \"split_config\": {\\n    \"splits\": [\\n      {\\n        \"hash_buckets\": 2,\\n        \"name\": \"train\"\\n      },\\n      {\\n        \"hash_buckets\": 1,\\n        \"name\": \"eval\"\\n      }\\n    ]\\n  }\\n}', 'input_config': '{\\n  \"splits\": [\\n    {\\n      \"name\": \"single_split\",\\n      \"pattern\": \"*\"\\n    }\\n  ]\\n}', 'output_file_format': 5, 'input_base': '/tmp/tfx-datamkxmix41', 'output_data_format': 6, 'span': 0, 'version': None, 'input_fingerprint': 'split:single_split,num_files:1,total_bytes:25648,xor_checksum:1652264510,sum_checksum:1652264510'}, execution_output_uri='pipelines/penguin-simple/CsvExampleGen/.system/executor_execution/1/executor_output.pb', stateful_working_dir='pipelines/penguin-simple/CsvExampleGen/.system/stateful_working_dir/2022-05-11T10:22:09.910052', tmp_dir='pipelines/penguin-simple/CsvExampleGen/.system/executor_execution/1/.temp/', pipeline_node=node_info {\n",
      "  type {\n",
      "    name: \"tfx.components.example_gen.csv_example_gen.component.CsvExampleGen\"\n",
      "  }\n",
      "  id: \"CsvExampleGen\"\n",
      "}\n",
      "contexts {\n",
      "  contexts {\n",
      "    type {\n",
      "      name: \"pipeline\"\n",
      "    }\n",
      "    name {\n",
      "      field_value {\n",
      "        string_value: \"penguin-simple\"\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "  contexts {\n",
      "    type {\n",
      "      name: \"pipeline_run\"\n",
      "    }\n",
      "    name {\n",
      "      field_value {\n",
      "        string_value: \"2022-05-11T10:22:09.910052\"\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "  contexts {\n",
      "    type {\n",
      "      name: \"node\"\n",
      "    }\n",
      "    name {\n",
      "      field_value {\n",
      "        string_value: \"penguin-simple.CsvExampleGen\"\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "}\n",
      "outputs {\n",
      "  outputs {\n",
      "    key: \"examples\"\n",
      "    value {\n",
      "      artifact_spec {\n",
      "        type {\n",
      "          name: \"Examples\"\n",
      "          properties {\n",
      "            key: \"span\"\n",
      "            value: INT\n",
      "          }\n",
      "          properties {\n",
      "            key: \"split_names\"\n",
      "            value: STRING\n",
      "          }\n",
      "          properties {\n",
      "            key: \"version\"\n",
      "            value: INT\n",
      "          }\n",
      "          base_type: DATASET\n",
      "        }\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "}\n",
      "parameters {\n",
      "  parameters {\n",
      "    key: \"input_base\"\n",
      "    value {\n",
      "      field_value {\n",
      "        string_value: \"/tmp/tfx-datamkxmix41\"\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "  parameters {\n",
      "    key: \"input_config\"\n",
      "    value {\n",
      "      field_value {\n",
      "        string_value: \"{\\n  \\\"splits\\\": [\\n    {\\n      \\\"name\\\": \\\"single_split\\\",\\n      \\\"pattern\\\": \\\"*\\\"\\n    }\\n  ]\\n}\"\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "  parameters {\n",
      "    key: \"output_config\"\n",
      "    value {\n",
      "      field_value {\n",
      "        string_value: \"{\\n  \\\"split_config\\\": {\\n    \\\"splits\\\": [\\n      {\\n        \\\"hash_buckets\\\": 2,\\n        \\\"name\\\": \\\"train\\\"\\n      },\\n      {\\n        \\\"hash_buckets\\\": 1,\\n        \\\"name\\\": \\\"eval\\\"\\n      }\\n    ]\\n  }\\n}\"\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "  parameters {\n",
      "    key: \"output_data_format\"\n",
      "    value {\n",
      "      field_value {\n",
      "        int_value: 6\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "  parameters {\n",
      "    key: \"output_file_format\"\n",
      "    value {\n",
      "      field_value {\n",
      "        int_value: 5\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "}\n",
      "downstream_nodes: \"Trainer\"\n",
      "execution_options {\n",
      "  caching_options {\n",
      "  }\n",
      "}\n",
      ", pipeline_info=id: \"penguin-simple\"\n",
      ", pipeline_run_id='2022-05-11T10:22:09.910052')\n",
      "INFO:absl:Generating examples.\n",
      "WARNING:apache_beam.runners.interactive.interactive_environment:Dependencies required for Interactive Beam PCollection visualization are not available, please use: `pip install apache-beam[interactive]` to install necessary dependencies to enable all data visualization features.\n"
     ]
    },
    {
     "data": {
      "application/javascript": [
       "\n",
       "        if (typeof window.interactive_beam_jquery == 'undefined') {\n",
       "          var jqueryScript = document.createElement('script');\n",
       "          jqueryScript.src = 'https://code.jquery.com/jquery-3.4.1.slim.min.js';\n",
       "          jqueryScript.type = 'text/javascript';\n",
       "          jqueryScript.onload = function() {\n",
       "            var datatableScript = document.createElement('script');\n",
       "            datatableScript.src = 'https://cdn.datatables.net/1.10.20/js/jquery.dataTables.min.js';\n",
       "            datatableScript.type = 'text/javascript';\n",
       "            datatableScript.onload = function() {\n",
       "              window.interactive_beam_jquery = jQuery.noConflict(true);\n",
       "              window.interactive_beam_jquery(document).ready(function($){\n",
       "                \n",
       "              });\n",
       "            }\n",
       "            document.head.appendChild(datatableScript);\n",
       "          };\n",
       "          document.head.appendChild(jqueryScript);\n",
       "        } else {\n",
       "          window.interactive_beam_jquery(document).ready(function($){\n",
       "            \n",
       "          });\n",
       "        }"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:absl:Processing input csv data /tmp/tfx-datamkxmix41/* to TFExample.\n",
      "WARNING:root:Make sure that locally built Python SDK docker image has Python 3.7 interpreter.\n",
      "E0511 10:22:10.903224886   12865 fork_posix.cc:70]           Fork support is only compatible with the epoll1 and poll polling strategies\n",
      "WARNING:apache_beam.io.tfrecordio:Couldn't find python-snappy so the implementation of _TFRecordUtil._masked_crc32c is not as fast as it could be.\n",
      "INFO:absl:Examples generated.\n",
      "INFO:absl:Value type <class 'NoneType'> of key version in exec_properties is not supported, going to drop it\n",
      "INFO:absl:Value type <class 'list'> of key _beam_pipeline_args in exec_properties is not supported, going to drop it\n",
      "INFO:absl:Cleaning up stateless execution info.\n",
      "INFO:absl:Execution 1 succeeded.\n",
      "INFO:absl:Cleaning up stateful execution info.\n",
      "INFO:absl:Publishing output artifacts defaultdict(<class 'list'>, {'examples': [Artifact(artifact: uri: \"pipelines/penguin-simple/CsvExampleGen/examples/1\"\n",
      "custom_properties {\n",
      "  key: \"input_fingerprint\"\n",
      "  value {\n",
      "    string_value: \"split:single_split,num_files:1,total_bytes:25648,xor_checksum:1652264510,sum_checksum:1652264510\"\n",
      "  }\n",
      "}\n",
      "custom_properties {\n",
      "  key: \"name\"\n",
      "  value {\n",
      "    string_value: \"penguin-simple:2022-05-11T10:22:09.910052:CsvExampleGen:examples:0\"\n",
      "  }\n",
      "}\n",
      "custom_properties {\n",
      "  key: \"span\"\n",
      "  value {\n",
      "    int_value: 0\n",
      "  }\n",
      "}\n",
      "custom_properties {\n",
      "  key: \"tfx_version\"\n",
      "  value {\n",
      "    string_value: \"1.7.1\"\n",
      "  }\n",
      "}\n",
      ", artifact_type: name: \"Examples\"\n",
      "properties {\n",
      "  key: \"span\"\n",
      "  value: INT\n",
      "}\n",
      "properties {\n",
      "  key: \"split_names\"\n",
      "  value: STRING\n",
      "}\n",
      "properties {\n",
      "  key: \"version\"\n",
      "  value: INT\n",
      "}\n",
      "base_type: DATASET\n",
      ")]}) for execution 1\n",
      "INFO:absl:MetadataStore with DB connection initialized\n",
      "INFO:absl:Component CsvExampleGen is finished.\n",
      "INFO:absl:Component Trainer is running.\n",
      "INFO:absl:Running launcher for node_info {\n",
      "  type {\n",
      "    name: \"tfx.components.trainer.component.Trainer\"\n",
      "    base_type: TRAIN\n",
      "  }\n",
      "  id: \"Trainer\"\n",
      "}\n",
      "contexts {\n",
      "  contexts {\n",
      "    type {\n",
      "      name: \"pipeline\"\n",
      "    }\n",
      "    name {\n",
      "      field_value {\n",
      "        string_value: \"penguin-simple\"\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "  contexts {\n",
      "    type {\n",
      "      name: \"pipeline_run\"\n",
      "    }\n",
      "    name {\n",
      "      field_value {\n",
      "        string_value: \"2022-05-11T10:22:09.910052\"\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "  contexts {\n",
      "    type {\n",
      "      name: \"node\"\n",
      "    }\n",
      "    name {\n",
      "      field_value {\n",
      "        string_value: \"penguin-simple.Trainer\"\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "}\n",
      "inputs {\n",
      "  inputs {\n",
      "    key: \"examples\"\n",
      "    value {\n",
      "      channels {\n",
      "        producer_node_query {\n",
      "          id: \"CsvExampleGen\"\n",
      "        }\n",
      "        context_queries {\n",
      "          type {\n",
      "            name: \"pipeline\"\n",
      "          }\n",
      "          name {\n",
      "            field_value {\n",
      "              string_value: \"penguin-simple\"\n",
      "            }\n",
      "          }\n",
      "        }\n",
      "        context_queries {\n",
      "          type {\n",
      "            name: \"pipeline_run\"\n",
      "          }\n",
      "          name {\n",
      "            field_value {\n",
      "              string_value: \"2022-05-11T10:22:09.910052\"\n",
      "            }\n",
      "          }\n",
      "        }\n",
      "        context_queries {\n",
      "          type {\n",
      "            name: \"node\"\n",
      "          }\n",
      "          name {\n",
      "            field_value {\n",
      "              string_value: \"penguin-simple.CsvExampleGen\"\n",
      "            }\n",
      "          }\n",
      "        }\n",
      "        artifact_query {\n",
      "          type {\n",
      "            name: \"Examples\"\n",
      "            base_type: DATASET\n",
      "          }\n",
      "        }\n",
      "        output_key: \"examples\"\n",
      "      }\n",
      "      min_count: 1\n",
      "    }\n",
      "  }\n",
      "}\n",
      "outputs {\n",
      "  outputs {\n",
      "    key: \"model\"\n",
      "    value {\n",
      "      artifact_spec {\n",
      "        type {\n",
      "          name: \"Model\"\n",
      "          base_type: MODEL\n",
      "        }\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "  outputs {\n",
      "    key: \"model_run\"\n",
      "    value {\n",
      "      artifact_spec {\n",
      "        type {\n",
      "          name: \"ModelRun\"\n",
      "        }\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "}\n",
      "parameters {\n",
      "  parameters {\n",
      "    key: \"custom_config\"\n",
      "    value {\n",
      "      field_value {\n",
      "        string_value: \"null\"\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "  parameters {\n",
      "    key: \"eval_args\"\n",
      "    value {\n",
      "      field_value {\n",
      "        string_value: \"{\\n  \\\"num_steps\\\": 5\\n}\"\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "  parameters {\n",
      "    key: \"module_path\"\n",
      "    value {\n",
      "      field_value {\n",
      "        string_value: \"penguin_trainer@pipelines/penguin-simple/_wheels/tfx_user_code_Trainer-0.0+a7e2e8dccbb913b74904edeec5549d868a2ea392bcd84fbc1965aba698dce3fc-py3-none-any.whl\"\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "  parameters {\n",
      "    key: \"train_args\"\n",
      "    value {\n",
      "      field_value {\n",
      "        string_value: \"{\\n  \\\"num_steps\\\": 100\\n}\"\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "}\n",
      "upstream_nodes: \"CsvExampleGen\"\n",
      "downstream_nodes: \"Pusher\"\n",
      "execution_options {\n",
      "  caching_options {\n",
      "  }\n",
      "}\n",
      "\n",
      "INFO:absl:MetadataStore with DB connection initialized\n",
      "INFO:absl:MetadataStore with DB connection initialized\n",
      "INFO:absl:Going to run a new execution 2\n",
      "INFO:absl:Going to run a new execution: ExecutionInfo(execution_id=2, input_dict={'examples': [Artifact(artifact: id: 1\n",
      "type_id: 15\n",
      "uri: \"pipelines/penguin-simple/CsvExampleGen/examples/1\"\n",
      "properties {\n",
      "  key: \"split_names\"\n",
      "  value {\n",
      "    string_value: \"[\\\"train\\\", \\\"eval\\\"]\"\n",
      "  }\n",
      "}\n",
      "custom_properties {\n",
      "  key: \"file_format\"\n",
      "  value {\n",
      "    string_value: \"tfrecords_gzip\"\n",
      "  }\n",
      "}\n",
      "custom_properties {\n",
      "  key: \"input_fingerprint\"\n",
      "  value {\n",
      "    string_value: \"split:single_split,num_files:1,total_bytes:25648,xor_checksum:1652264510,sum_checksum:1652264510\"\n",
      "  }\n",
      "}\n",
      "custom_properties {\n",
      "  key: \"name\"\n",
      "  value {\n",
      "    string_value: \"penguin-simple:2022-05-11T10:22:09.910052:CsvExampleGen:examples:0\"\n",
      "  }\n",
      "}\n",
      "custom_properties {\n",
      "  key: \"payload_format\"\n",
      "  value {\n",
      "    string_value: \"FORMAT_TF_EXAMPLE\"\n",
      "  }\n",
      "}\n",
      "custom_properties {\n",
      "  key: \"span\"\n",
      "  value {\n",
      "    int_value: 0\n",
      "  }\n",
      "}\n",
      "custom_properties {\n",
      "  key: \"tfx_version\"\n",
      "  value {\n",
      "    string_value: \"1.7.1\"\n",
      "  }\n",
      "}\n",
      "state: LIVE\n",
      "create_time_since_epoch: 1652264531581\n",
      "last_update_time_since_epoch: 1652264531581\n",
      ", artifact_type: id: 15\n",
      "name: \"Examples\"\n",
      "properties {\n",
      "  key: \"span\"\n",
      "  value: INT\n",
      "}\n",
      "properties {\n",
      "  key: \"split_names\"\n",
      "  value: STRING\n",
      "}\n",
      "properties {\n",
      "  key: \"version\"\n",
      "  value: INT\n",
      "}\n",
      "base_type: DATASET\n",
      ")]}, output_dict=defaultdict(<class 'list'>, {'model': [Artifact(artifact: uri: \"pipelines/penguin-simple/Trainer/model/2\"\n",
      "custom_properties {\n",
      "  key: \"name\"\n",
      "  value {\n",
      "    string_value: \"penguin-simple:2022-05-11T10:22:09.910052:Trainer:model:0\"\n",
      "  }\n",
      "}\n",
      ", artifact_type: name: \"Model\"\n",
      "base_type: MODEL\n",
      ")], 'model_run': [Artifact(artifact: uri: \"pipelines/penguin-simple/Trainer/model_run/2\"\n",
      "custom_properties {\n",
      "  key: \"name\"\n",
      "  value {\n",
      "    string_value: \"penguin-simple:2022-05-11T10:22:09.910052:Trainer:model_run:0\"\n",
      "  }\n",
      "}\n",
      ", artifact_type: name: \"ModelRun\"\n",
      ")]}), exec_properties={'custom_config': 'null', 'eval_args': '{\\n  \"num_steps\": 5\\n}', 'train_args': '{\\n  \"num_steps\": 100\\n}', 'module_path': 'penguin_trainer@pipelines/penguin-simple/_wheels/tfx_user_code_Trainer-0.0+a7e2e8dccbb913b74904edeec5549d868a2ea392bcd84fbc1965aba698dce3fc-py3-none-any.whl'}, execution_output_uri='pipelines/penguin-simple/Trainer/.system/executor_execution/2/executor_output.pb', stateful_working_dir='pipelines/penguin-simple/Trainer/.system/stateful_working_dir/2022-05-11T10:22:09.910052', tmp_dir='pipelines/penguin-simple/Trainer/.system/executor_execution/2/.temp/', pipeline_node=node_info {\n",
      "  type {\n",
      "    name: \"tfx.components.trainer.component.Trainer\"\n",
      "    base_type: TRAIN\n",
      "  }\n",
      "  id: \"Trainer\"\n",
      "}\n",
      "contexts {\n",
      "  contexts {\n",
      "    type {\n",
      "      name: \"pipeline\"\n",
      "    }\n",
      "    name {\n",
      "      field_value {\n",
      "        string_value: \"penguin-simple\"\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "  contexts {\n",
      "    type {\n",
      "      name: \"pipeline_run\"\n",
      "    }\n",
      "    name {\n",
      "      field_value {\n",
      "        string_value: \"2022-05-11T10:22:09.910052\"\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "  contexts {\n",
      "    type {\n",
      "      name: \"node\"\n",
      "    }\n",
      "    name {\n",
      "      field_value {\n",
      "        string_value: \"penguin-simple.Trainer\"\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "}\n",
      "inputs {\n",
      "  inputs {\n",
      "    key: \"examples\"\n",
      "    value {\n",
      "      channels {\n",
      "        producer_node_query {\n",
      "          id: \"CsvExampleGen\"\n",
      "        }\n",
      "        context_queries {\n",
      "          type {\n",
      "            name: \"pipeline\"\n",
      "          }\n",
      "          name {\n",
      "            field_value {\n",
      "              string_value: \"penguin-simple\"\n",
      "            }\n",
      "          }\n",
      "        }\n",
      "        context_queries {\n",
      "          type {\n",
      "            name: \"pipeline_run\"\n",
      "          }\n",
      "          name {\n",
      "            field_value {\n",
      "              string_value: \"2022-05-11T10:22:09.910052\"\n",
      "            }\n",
      "          }\n",
      "        }\n",
      "        context_queries {\n",
      "          type {\n",
      "            name: \"node\"\n",
      "          }\n",
      "          name {\n",
      "            field_value {\n",
      "              string_value: \"penguin-simple.CsvExampleGen\"\n",
      "            }\n",
      "          }\n",
      "        }\n",
      "        artifact_query {\n",
      "          type {\n",
      "            name: \"Examples\"\n",
      "            base_type: DATASET\n",
      "          }\n",
      "        }\n",
      "        output_key: \"examples\"\n",
      "      }\n",
      "      min_count: 1\n",
      "    }\n",
      "  }\n",
      "}\n",
      "outputs {\n",
      "  outputs {\n",
      "    key: \"model\"\n",
      "    value {\n",
      "      artifact_spec {\n",
      "        type {\n",
      "          name: \"Model\"\n",
      "          base_type: MODEL\n",
      "        }\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "  outputs {\n",
      "    key: \"model_run\"\n",
      "    value {\n",
      "      artifact_spec {\n",
      "        type {\n",
      "          name: \"ModelRun\"\n",
      "        }\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "}\n",
      "parameters {\n",
      "  parameters {\n",
      "    key: \"custom_config\"\n",
      "    value {\n",
      "      field_value {\n",
      "        string_value: \"null\"\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "  parameters {\n",
      "    key: \"eval_args\"\n",
      "    value {\n",
      "      field_value {\n",
      "        string_value: \"{\\n  \\\"num_steps\\\": 5\\n}\"\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "  parameters {\n",
      "    key: \"module_path\"\n",
      "    value {\n",
      "      field_value {\n",
      "        string_value: \"penguin_trainer@pipelines/penguin-simple/_wheels/tfx_user_code_Trainer-0.0+a7e2e8dccbb913b74904edeec5549d868a2ea392bcd84fbc1965aba698dce3fc-py3-none-any.whl\"\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "  parameters {\n",
      "    key: \"train_args\"\n",
      "    value {\n",
      "      field_value {\n",
      "        string_value: \"{\\n  \\\"num_steps\\\": 100\\n}\"\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "}\n",
      "upstream_nodes: \"CsvExampleGen\"\n",
      "downstream_nodes: \"Pusher\"\n",
      "execution_options {\n",
      "  caching_options {\n",
      "  }\n",
      "}\n",
      ", pipeline_info=id: \"penguin-simple\"\n",
      ", pipeline_run_id='2022-05-11T10:22:09.910052')\n",
      "INFO:absl:Train on the 'train' split when train_args.splits is not set.\n",
      "INFO:absl:Evaluate on the 'eval' split when eval_args.splits is not set.\n",
      "INFO:absl:udf_utils.get_fn {'custom_config': 'null', 'eval_args': '{\\n  \"num_steps\": 5\\n}', 'train_args': '{\\n  \"num_steps\": 100\\n}', 'module_path': 'penguin_trainer@pipelines/penguin-simple/_wheels/tfx_user_code_Trainer-0.0+a7e2e8dccbb913b74904edeec5549d868a2ea392bcd84fbc1965aba698dce3fc-py3-none-any.whl'} 'run_fn'\n",
      "INFO:absl:Installing 'pipelines/penguin-simple/_wheels/tfx_user_code_Trainer-0.0+a7e2e8dccbb913b74904edeec5549d868a2ea392bcd84fbc1965aba698dce3fc-py3-none-any.whl' to a temporary directory.\n",
      "INFO:absl:Executing: ['/opt/conda/bin/python', '-m', 'pip', 'install', '--target', '/tmp/tmpi5ca2dby', 'pipelines/penguin-simple/_wheels/tfx_user_code_Trainer-0.0+a7e2e8dccbb913b74904edeec5549d868a2ea392bcd84fbc1965aba698dce3fc-py3-none-any.whl']\n",
      "E0511 10:22:11.650499610   12865 fork_posix.cc:70]           Fork support is only compatible with the epoll1 and poll polling strategies\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Processing ./pipelines/penguin-simple/_wheels/tfx_user_code_Trainer-0.0+a7e2e8dccbb913b74904edeec5549d868a2ea392bcd84fbc1965aba698dce3fc-py3-none-any.whl\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:absl:Successfully installed 'pipelines/penguin-simple/_wheels/tfx_user_code_Trainer-0.0+a7e2e8dccbb913b74904edeec5549d868a2ea392bcd84fbc1965aba698dce3fc-py3-none-any.whl'.\n",
      "INFO:absl:Training model.\n",
      "INFO:absl:Feature body_mass_g has a shape dim {\n",
      "  size: 1\n",
      "}\n",
      ". Setting to DenseTensor.\n",
      "INFO:absl:Feature culmen_depth_mm has a shape dim {\n",
      "  size: 1\n",
      "}\n",
      ". Setting to DenseTensor.\n",
      "INFO:absl:Feature culmen_length_mm has a shape dim {\n",
      "  size: 1\n",
      "}\n",
      ". Setting to DenseTensor.\n",
      "INFO:absl:Feature flipper_length_mm has a shape dim {\n",
      "  size: 1\n",
      "}\n",
      ". Setting to DenseTensor.\n",
      "INFO:absl:Feature species has a shape dim {\n",
      "  size: 1\n",
      "}\n",
      ". Setting to DenseTensor.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Installing collected packages: tfx-user-code-Trainer\n",
      "Successfully installed tfx-user-code-Trainer-0.0+a7e2e8dccbb913b74904edeec5549d868a2ea392bcd84fbc1965aba698dce3fc\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "2022-05-11 10:22:14.696391: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcuda.so.1'; dlerror: libcuda.so.1: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /usr/local/cuda/lib64:/usr/local/nccl2/lib:/usr/local/cuda/extras/CUPTI/lib64\n",
      "2022-05-11 10:22:14.696439: W tensorflow/stream_executor/cuda/cuda_driver.cc:269] failed call to cuInit: UNKNOWN ERROR (303)\n",
      "2022-05-11 10:22:14.696467: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:156] kernel driver does not appear to be running on this host (tensorflow-2-6-20220511-154240): /proc/driver/nvidia/version does not exist\n",
      "2022-05-11 10:22:14.696746: I tensorflow/core/platform/cpu_feature_guard.cc:151] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations:  AVX2 FMA\n",
      "To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.\n",
      "INFO:absl:Feature body_mass_g has a shape dim {\n",
      "  size: 1\n",
      "}\n",
      ". Setting to DenseTensor.\n",
      "INFO:absl:Feature culmen_depth_mm has a shape dim {\n",
      "  size: 1\n",
      "}\n",
      ". Setting to DenseTensor.\n",
      "INFO:absl:Feature culmen_length_mm has a shape dim {\n",
      "  size: 1\n",
      "}\n",
      ". Setting to DenseTensor.\n",
      "INFO:absl:Feature flipper_length_mm has a shape dim {\n",
      "  size: 1\n",
      "}\n",
      ". Setting to DenseTensor.\n",
      "INFO:absl:Feature species has a shape dim {\n",
      "  size: 1\n",
      "}\n",
      ". Setting to DenseTensor.\n",
      "INFO:absl:Feature body_mass_g has a shape dim {\n",
      "  size: 1\n",
      "}\n",
      ". Setting to DenseTensor.\n",
      "INFO:absl:Feature culmen_depth_mm has a shape dim {\n",
      "  size: 1\n",
      "}\n",
      ". Setting to DenseTensor.\n",
      "INFO:absl:Feature culmen_length_mm has a shape dim {\n",
      "  size: 1\n",
      "}\n",
      ". Setting to DenseTensor.\n",
      "INFO:absl:Feature flipper_length_mm has a shape dim {\n",
      "  size: 1\n",
      "}\n",
      ". Setting to DenseTensor.\n",
      "INFO:absl:Feature species has a shape dim {\n",
      "  size: 1\n",
      "}\n",
      ". Setting to DenseTensor.\n",
      "INFO:absl:Feature body_mass_g has a shape dim {\n",
      "  size: 1\n",
      "}\n",
      ". Setting to DenseTensor.\n",
      "INFO:absl:Feature culmen_depth_mm has a shape dim {\n",
      "  size: 1\n",
      "}\n",
      ". Setting to DenseTensor.\n",
      "INFO:absl:Feature culmen_length_mm has a shape dim {\n",
      "  size: 1\n",
      "}\n",
      ". Setting to DenseTensor.\n",
      "INFO:absl:Feature flipper_length_mm has a shape dim {\n",
      "  size: 1\n",
      "}\n",
      ". Setting to DenseTensor.\n",
      "INFO:absl:Feature species has a shape dim {\n",
      "  size: 1\n",
      "}\n",
      ". Setting to DenseTensor.\n",
      "INFO:absl:Model: \"model\"\n",
      "INFO:absl:__________________________________________________________________________________________________\n",
      "INFO:absl: Layer (type)                   Output Shape         Param #     Connected to                     \n",
      "INFO:absl:==================================================================================================\n",
      "INFO:absl: culmen_length_mm (InputLayer)  [(None, 1)]          0           []                               \n",
      "INFO:absl:                                                                                                  \n",
      "INFO:absl: culmen_depth_mm (InputLayer)   [(None, 1)]          0           []                               \n",
      "INFO:absl:                                                                                                  \n",
      "INFO:absl: flipper_length_mm (InputLayer)  [(None, 1)]         0           []                               \n",
      "INFO:absl:                                                                                                  \n",
      "INFO:absl: body_mass_g (InputLayer)       [(None, 1)]          0           []                               \n",
      "INFO:absl:                                                                                                  \n",
      "INFO:absl: concatenate (Concatenate)      (None, 4)            0           ['culmen_length_mm[0][0]',       \n",
      "INFO:absl:                                                                  'culmen_depth_mm[0][0]',        \n",
      "INFO:absl:                                                                  'flipper_length_mm[0][0]',      \n",
      "INFO:absl:                                                                  'body_mass_g[0][0]']            \n",
      "INFO:absl:                                                                                                  \n",
      "INFO:absl: dense (Dense)                  (None, 8)            40          ['concatenate[0][0]']            \n",
      "INFO:absl:                                                                                                  \n",
      "INFO:absl: dense_1 (Dense)                (None, 8)            72          ['dense[0][0]']                  \n",
      "INFO:absl:                                                                                                  \n",
      "INFO:absl: dense_2 (Dense)                (None, 3)            27          ['dense_1[0][0]']                \n",
      "INFO:absl:                                                                                                  \n",
      "INFO:absl:==================================================================================================\n",
      "INFO:absl:Total params: 139\n",
      "INFO:absl:Trainable params: 139\n",
      "INFO:absl:Non-trainable params: 0\n",
      "INFO:absl:__________________________________________________________________________________________________\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "100/100 [==============================] - 1s 3ms/step - loss: 0.6242 - sparse_categorical_accuracy: 0.7715 - val_loss: 0.1633 - val_sparse_categorical_accuracy: 0.9600\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "2022-05-11 10:22:16.418707: W tensorflow/python/util/util.cc:368] Sets are not currently considered sequences, but this may change in the future, so consider avoiding using them.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Assets written to: pipelines/penguin-simple/Trainer/model/2/Format-Serving/assets\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Assets written to: pipelines/penguin-simple/Trainer/model/2/Format-Serving/assets\n",
      "INFO:absl:Training complete. Model written to pipelines/penguin-simple/Trainer/model/2/Format-Serving. ModelRun written to pipelines/penguin-simple/Trainer/model_run/2\n",
      "INFO:absl:Cleaning up stateless execution info.\n",
      "INFO:absl:Execution 2 succeeded.\n",
      "INFO:absl:Cleaning up stateful execution info.\n",
      "INFO:absl:Publishing output artifacts defaultdict(<class 'list'>, {'model': [Artifact(artifact: uri: \"pipelines/penguin-simple/Trainer/model/2\"\n",
      "custom_properties {\n",
      "  key: \"name\"\n",
      "  value {\n",
      "    string_value: \"penguin-simple:2022-05-11T10:22:09.910052:Trainer:model:0\"\n",
      "  }\n",
      "}\n",
      "custom_properties {\n",
      "  key: \"tfx_version\"\n",
      "  value {\n",
      "    string_value: \"1.7.1\"\n",
      "  }\n",
      "}\n",
      ", artifact_type: name: \"Model\"\n",
      "base_type: MODEL\n",
      ")], 'model_run': [Artifact(artifact: uri: \"pipelines/penguin-simple/Trainer/model_run/2\"\n",
      "custom_properties {\n",
      "  key: \"name\"\n",
      "  value {\n",
      "    string_value: \"penguin-simple:2022-05-11T10:22:09.910052:Trainer:model_run:0\"\n",
      "  }\n",
      "}\n",
      "custom_properties {\n",
      "  key: \"tfx_version\"\n",
      "  value {\n",
      "    string_value: \"1.7.1\"\n",
      "  }\n",
      "}\n",
      ", artifact_type: name: \"ModelRun\"\n",
      ")]}) for execution 2\n",
      "INFO:absl:MetadataStore with DB connection initialized\n",
      "INFO:absl:Component Trainer is finished.\n",
      "INFO:absl:Component Pusher is running.\n",
      "INFO:absl:Running launcher for node_info {\n",
      "  type {\n",
      "    name: \"tfx.components.pusher.component.Pusher\"\n",
      "    base_type: DEPLOY\n",
      "  }\n",
      "  id: \"Pusher\"\n",
      "}\n",
      "contexts {\n",
      "  contexts {\n",
      "    type {\n",
      "      name: \"pipeline\"\n",
      "    }\n",
      "    name {\n",
      "      field_value {\n",
      "        string_value: \"penguin-simple\"\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "  contexts {\n",
      "    type {\n",
      "      name: \"pipeline_run\"\n",
      "    }\n",
      "    name {\n",
      "      field_value {\n",
      "        string_value: \"2022-05-11T10:22:09.910052\"\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "  contexts {\n",
      "    type {\n",
      "      name: \"node\"\n",
      "    }\n",
      "    name {\n",
      "      field_value {\n",
      "        string_value: \"penguin-simple.Pusher\"\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "}\n",
      "inputs {\n",
      "  inputs {\n",
      "    key: \"model\"\n",
      "    value {\n",
      "      channels {\n",
      "        producer_node_query {\n",
      "          id: \"Trainer\"\n",
      "        }\n",
      "        context_queries {\n",
      "          type {\n",
      "            name: \"pipeline\"\n",
      "          }\n",
      "          name {\n",
      "            field_value {\n",
      "              string_value: \"penguin-simple\"\n",
      "            }\n",
      "          }\n",
      "        }\n",
      "        context_queries {\n",
      "          type {\n",
      "            name: \"pipeline_run\"\n",
      "          }\n",
      "          name {\n",
      "            field_value {\n",
      "              string_value: \"2022-05-11T10:22:09.910052\"\n",
      "            }\n",
      "          }\n",
      "        }\n",
      "        context_queries {\n",
      "          type {\n",
      "            name: \"node\"\n",
      "          }\n",
      "          name {\n",
      "            field_value {\n",
      "              string_value: \"penguin-simple.Trainer\"\n",
      "            }\n",
      "          }\n",
      "        }\n",
      "        artifact_query {\n",
      "          type {\n",
      "            name: \"Model\"\n",
      "            base_type: MODEL\n",
      "          }\n",
      "        }\n",
      "        output_key: \"model\"\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "}\n",
      "outputs {\n",
      "  outputs {\n",
      "    key: \"pushed_model\"\n",
      "    value {\n",
      "      artifact_spec {\n",
      "        type {\n",
      "          name: \"PushedModel\"\n",
      "          base_type: MODEL\n",
      "        }\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "}\n",
      "parameters {\n",
      "  parameters {\n",
      "    key: \"custom_config\"\n",
      "    value {\n",
      "      field_value {\n",
      "        string_value: \"null\"\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "  parameters {\n",
      "    key: \"push_destination\"\n",
      "    value {\n",
      "      field_value {\n",
      "        string_value: \"{\\n  \\\"filesystem\\\": {\\n    \\\"base_directory\\\": \\\"serving_model/penguin-simple\\\"\\n  }\\n}\"\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "}\n",
      "upstream_nodes: \"Trainer\"\n",
      "execution_options {\n",
      "  caching_options {\n",
      "  }\n",
      "}\n",
      "\n",
      "INFO:absl:MetadataStore with DB connection initialized\n",
      "INFO:absl:MetadataStore with DB connection initialized\n",
      "INFO:absl:Going to run a new execution 3\n",
      "INFO:absl:Going to run a new execution: ExecutionInfo(execution_id=3, input_dict={'model': [Artifact(artifact: id: 2\n",
      "type_id: 17\n",
      "uri: \"pipelines/penguin-simple/Trainer/model/2\"\n",
      "custom_properties {\n",
      "  key: \"name\"\n",
      "  value {\n",
      "    string_value: \"penguin-simple:2022-05-11T10:22:09.910052:Trainer:model:0\"\n",
      "  }\n",
      "}\n",
      "custom_properties {\n",
      "  key: \"tfx_version\"\n",
      "  value {\n",
      "    string_value: \"1.7.1\"\n",
      "  }\n",
      "}\n",
      "state: LIVE\n",
      "create_time_since_epoch: 1652264536906\n",
      "last_update_time_since_epoch: 1652264536906\n",
      ", artifact_type: id: 17\n",
      "name: \"Model\"\n",
      "base_type: MODEL\n",
      ")]}, output_dict=defaultdict(<class 'list'>, {'pushed_model': [Artifact(artifact: uri: \"pipelines/penguin-simple/Pusher/pushed_model/3\"\n",
      "custom_properties {\n",
      "  key: \"name\"\n",
      "  value {\n",
      "    string_value: \"penguin-simple:2022-05-11T10:22:09.910052:Pusher:pushed_model:0\"\n",
      "  }\n",
      "}\n",
      ", artifact_type: name: \"PushedModel\"\n",
      "base_type: MODEL\n",
      ")]}), exec_properties={'push_destination': '{\\n  \"filesystem\": {\\n    \"base_directory\": \"serving_model/penguin-simple\"\\n  }\\n}', 'custom_config': 'null'}, execution_output_uri='pipelines/penguin-simple/Pusher/.system/executor_execution/3/executor_output.pb', stateful_working_dir='pipelines/penguin-simple/Pusher/.system/stateful_working_dir/2022-05-11T10:22:09.910052', tmp_dir='pipelines/penguin-simple/Pusher/.system/executor_execution/3/.temp/', pipeline_node=node_info {\n",
      "  type {\n",
      "    name: \"tfx.components.pusher.component.Pusher\"\n",
      "    base_type: DEPLOY\n",
      "  }\n",
      "  id: \"Pusher\"\n",
      "}\n",
      "contexts {\n",
      "  contexts {\n",
      "    type {\n",
      "      name: \"pipeline\"\n",
      "    }\n",
      "    name {\n",
      "      field_value {\n",
      "        string_value: \"penguin-simple\"\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "  contexts {\n",
      "    type {\n",
      "      name: \"pipeline_run\"\n",
      "    }\n",
      "    name {\n",
      "      field_value {\n",
      "        string_value: \"2022-05-11T10:22:09.910052\"\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "  contexts {\n",
      "    type {\n",
      "      name: \"node\"\n",
      "    }\n",
      "    name {\n",
      "      field_value {\n",
      "        string_value: \"penguin-simple.Pusher\"\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "}\n",
      "inputs {\n",
      "  inputs {\n",
      "    key: \"model\"\n",
      "    value {\n",
      "      channels {\n",
      "        producer_node_query {\n",
      "          id: \"Trainer\"\n",
      "        }\n",
      "        context_queries {\n",
      "          type {\n",
      "            name: \"pipeline\"\n",
      "          }\n",
      "          name {\n",
      "            field_value {\n",
      "              string_value: \"penguin-simple\"\n",
      "            }\n",
      "          }\n",
      "        }\n",
      "        context_queries {\n",
      "          type {\n",
      "            name: \"pipeline_run\"\n",
      "          }\n",
      "          name {\n",
      "            field_value {\n",
      "              string_value: \"2022-05-11T10:22:09.910052\"\n",
      "            }\n",
      "          }\n",
      "        }\n",
      "        context_queries {\n",
      "          type {\n",
      "            name: \"node\"\n",
      "          }\n",
      "          name {\n",
      "            field_value {\n",
      "              string_value: \"penguin-simple.Trainer\"\n",
      "            }\n",
      "          }\n",
      "        }\n",
      "        artifact_query {\n",
      "          type {\n",
      "            name: \"Model\"\n",
      "            base_type: MODEL\n",
      "          }\n",
      "        }\n",
      "        output_key: \"model\"\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "}\n",
      "outputs {\n",
      "  outputs {\n",
      "    key: \"pushed_model\"\n",
      "    value {\n",
      "      artifact_spec {\n",
      "        type {\n",
      "          name: \"PushedModel\"\n",
      "          base_type: MODEL\n",
      "        }\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "}\n",
      "parameters {\n",
      "  parameters {\n",
      "    key: \"custom_config\"\n",
      "    value {\n",
      "      field_value {\n",
      "        string_value: \"null\"\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "  parameters {\n",
      "    key: \"push_destination\"\n",
      "    value {\n",
      "      field_value {\n",
      "        string_value: \"{\\n  \\\"filesystem\\\": {\\n    \\\"base_directory\\\": \\\"serving_model/penguin-simple\\\"\\n  }\\n}\"\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "}\n",
      "upstream_nodes: \"Trainer\"\n",
      "execution_options {\n",
      "  caching_options {\n",
      "  }\n",
      "}\n",
      ", pipeline_info=id: \"penguin-simple\"\n",
      ", pipeline_run_id='2022-05-11T10:22:09.910052')\n",
      "WARNING:absl:Pusher is going to push the model without validation. Consider using Evaluator or InfraValidator in your pipeline.\n",
      "INFO:absl:Model version: 1652264536\n",
      "INFO:absl:Model written to serving path serving_model/penguin-simple/1652264536.\n",
      "INFO:absl:Model pushed to pipelines/penguin-simple/Pusher/pushed_model/3.\n",
      "INFO:absl:Cleaning up stateless execution info.\n",
      "INFO:absl:Execution 3 succeeded.\n",
      "INFO:absl:Cleaning up stateful execution info.\n",
      "INFO:absl:Publishing output artifacts defaultdict(<class 'list'>, {'pushed_model': [Artifact(artifact: uri: \"pipelines/penguin-simple/Pusher/pushed_model/3\"\n",
      "custom_properties {\n",
      "  key: \"name\"\n",
      "  value {\n",
      "    string_value: \"penguin-simple:2022-05-11T10:22:09.910052:Pusher:pushed_model:0\"\n",
      "  }\n",
      "}\n",
      "custom_properties {\n",
      "  key: \"tfx_version\"\n",
      "  value {\n",
      "    string_value: \"1.7.1\"\n",
      "  }\n",
      "}\n",
      ", artifact_type: name: \"PushedModel\"\n",
      "base_type: MODEL\n",
      ")]}) for execution 3\n",
      "INFO:absl:MetadataStore with DB connection initialized\n",
      "INFO:absl:Component Pusher is finished.\n"
     ]
    }
   ],
   "source": [
    "tfx.orchestration.LocalDagRunner().run(\n",
    "  _create_pipeline(\n",
    "      pipeline_name=PIPELINE_NAME,\n",
    "      pipeline_root=PIPELINE_ROOT,\n",
    "      data_root=DATA_ROOT,\n",
    "      module_file=_trainer_module_file,\n",
    "      serving_model_dir=SERVING_MODEL_DIR,\n",
    "      metadata_path=METADATA_PATH))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "ppERq0Mj6xvW"
   },
   "source": [
    "You should see \"INFO:absl:Component Pusher is finished.\" at the end of the\n",
    "logs if the pipeline finished successfully. Because `Pusher` component is the\n",
    "last component of the pipeline.\n",
    "\n",
    "The pusher component pushes the trained model to the `SERVING_MODEL_DIR` which\n",
    "is the `serving_model/penguin-simple` directory if you did not change the\n",
    "variables in the previous steps. You can see the result from the file browser\n",
    "in the left-side panel in Colab, or using the following command:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "NTHROkqX6yHx",
    "outputId": "3946c94a-af5f-40ef-aa69-cf9b0d991a71"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "serving_model/penguin-simple\n",
      "serving_model/penguin-simple/1652264536\n",
      "serving_model/penguin-simple/1652264536/keras_metadata.pb\n",
      "serving_model/penguin-simple/1652264536/variables\n",
      "serving_model/penguin-simple/1652264536/variables/variables.index\n",
      "serving_model/penguin-simple/1652264536/variables/variables.data-00000-of-00001\n",
      "serving_model/penguin-simple/1652264536/saved_model.pb\n",
      "serving_model/penguin-simple/1652264536/assets\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "E0511 10:23:38.130596983   12865 fork_posix.cc:70]           Fork support is only compatible with the epoll1 and poll polling strategies\n"
     ]
    }
   ],
   "source": [
    "# TODO 3\n",
    "# List files in created model directory.\n",
    "!find {SERVING_MODEL_DIR}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "08R8qvweThRf"
   },
   "source": [
    "## Next steps\n",
    "\n",
    "You can find more resources on https://www.tensorflow.org/tfx/tutorials.\n",
    "\n",
    "Please see\n",
    "[Understanding TFX Pipelines](https://www.tensorflow.org/tfx/guide/understanding_tfx_pipelines)\n",
    "to learn more about various concepts in TFX.\n"
   ]
  }
 ],
 "metadata": {
  "colab": {
   "collapsed_sections": [
    "DjUA6S30k52h"
   ],
   "name": "penguin_simple.ipynb",
   "provenance": [],
   "toc_visible": true
  },
  "environment": {
   "kernel": "python3",
   "name": "tf2-gpu.2-6.m91",
   "type": "gcloud",
   "uri": "gcr.io/deeplearning-platform-release/tf2-gpu.2-6:m91"
  },
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
